Mysql
 sql >> Database >  >> RDS >> Mysql

Postgresl select count(*) richiede molto tempo

La seconda istruzione richiede molto tempo perché deve scansionare l'intera tabella per contare le righe.

Una cosa che puoi fare è usare un indice:

CREATE INDEX ON tbl_oplog (deleted) INCLUDE (id);
VACUUM tbl_oplog;  -- so you get an index only scan

Supponendo che id è la chiave primaria, sarebbe molto meglio usare count(*) e ometti INCLUDE clausola dall'indice.

Ma la cosa migliore è probabilmente utilizzare un preventivo:

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 = ?;

Questo utilizza le statistiche di distribuzione per stimare il conteggio desiderato.

Se si tratta solo di impaginazione, non hai bisogno di conteggi esatti.

Leggi il mio blog per ulteriori informazioni sull'argomento del conteggio in PostgreSQL.