La deuxième instruction prend beaucoup de temps car elle doit parcourir toute la table afin de compter les lignes.
Une chose que vous pouvez faire est d'utiliser un index :
CREATE INDEX ON tbl_oplog (deleted) INCLUDE (id);
VACUUM tbl_oplog; -- so you get an index only scan
En supposant que id
est la clé primaire, il serait préférable d'utiliser count(*)
et omettez le INCLUDE
clause de l'index.
Mais le mieux est probablement d'utiliser une estimation :
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 = ?;
Cela utilise les statistiques de distribution pour estimer le nombre souhaité.
S'il ne s'agit que de pagination, vous n'avez pas besoin de nombres exacts.
Lisez mon blog pour en savoir plus sur le comptage dans PostgreSQL.