Câu lệnh thứ hai mất nhiều thời gian vì nó phải quét toàn bộ bảng để đếm các hàng.
Một điều bạn có thể làm là sử dụng chỉ mục:
CREATE INDEX ON tbl_oplog (deleted) INCLUDE (id);
VACUUM tbl_oplog; -- so you get an index only scan
Giả sử rằng id
là khóa chính, sẽ tốt hơn nhiều nếu sử dụng count(*)
và bỏ qua INCLUDE
mệnh đề từ chỉ mục.
Nhưng tốt nhất có lẽ là sử dụng một ước tính:
SELECT t.reltuples * freq.f AS estimated_rows
FROM pg_stats AS s
JOIN pg_namespace AS n
ON s.schemaname = n.nspname
JOIN pg_class AS t
ON s.tablename = t.relname
AND n.oid = t.relnamespace
CROSS JOIN LATERAL
unnest(s.most_common_vals::text::boolean[]) WITH ORDINALITY AS val(v,id)
JOIN LATERAL
unnest(s.most_common_freqs) WITH ORDINALITY AS freq(f,id)
USING (id)
WHERE s.tablename = 'tbl_oplog'
AND s.attname = 'deleted'
AND val.v = ?;
Điều này sử dụng thống kê phân phối để ước tính số lượng mong muốn.
Nếu đó chỉ là về phân trang, bạn không cần số lượng chính xác.
Đọc blog của tôi để biết thêm về chủ đề đếm trong PostgreSQL.