La segunda declaración lleva mucho tiempo porque tiene que escanear toda la tabla para contar las filas.
Una cosa que puedes hacer es usar un índice:
CREATE INDEX ON tbl_oplog (deleted) INCLUDE (id);
VACUUM tbl_oplog; -- so you get an index only scan
Asumiendo que id
es la clave principal, sería mucho mejor usar count(*)
y omitir INCLUDE
cláusula del índice.
Pero probablemente lo mejor sea usar una estimación:
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 = ?;
Esto utiliza las estadísticas de distribución para estimar el conteo deseado.
Si solo se trata de paginación, no necesita recuentos exactos.
Lea mi blog para obtener más información sobre el tema de contar en PostgreSQL.