[postgresql-it] Re: query plan

  • From: Fabio Pardi <f.pardi@xxxxxxxxxxxx>
  • To: postgresql-it@xxxxxxxxxxxxx
  • Date: Tue, 4 Jun 2019 12:33:16 +0200

Ciao,

considerando che il query planner cerca di trovare l accesso piu veloce ai 
dati, la risposta al tuo quesito e' probabilmente da ricercarsi nella parte 
discriminante delle query e non nel tipo di dato (varchar).

In altre parole: una query usa

WHERE nome_rep LIKE 'Preparativa' AND creato_il > TO_DATE('2019-05-01', 
'DD-MM-YYYY');

l'altra

WHERE nome = 'dati studi' AND creato_il > TO_DATE('2019-05-01', 'DD-MM-YYYY');


Detto questo, considera che un indice viene usato se stai solo accedendo a 
parte dei dati (quanti? dipende).

Per esempio: se hai molti record nome = 'dati studi', l indice non e' 
efficiente ed e' meglio fare uno scan di tutta la tabella.

Inoltre, assicurati che le statistiche siano aggiornate (analyze).


saluti,

fabio pardi



On 04/06/2019 12:12, Piviul wrote:

Ciao a tutti, sto cercando di capire qualcosa sui query plan e avrei bisogno 
di qualche delucidazione...

Questi sono i query plan di 2 query molto simili fra loro sulla stessa 
tabella:
EXPLAIN ANALYZE SELECT id FROM backup_studi.t_archivi WHERE nome_rep LIKE 
'Preparativa' AND creato_il > TO_DATE('2019-05-01', 'DD-MM-YYYY');
"Index Scan using t_archivi_nome_rep_idx on t_archivi (cost=0.00..84376.07 
rows=62473 width=8) (actual time=0.076..58.521 rows=57747 loops=1)"
"  Index Cond: ((nome_rep)::text = 'Preparativa'::text)"
"  Filter: (((nome_rep)::text ~~ 'Preparativa'::text) AND (creato_il > 
to_date('2019-05-01'::text, 'DD-MM-YYYY'::text)))"
"Total runtime: 60.731 ms"

EXPLAIN ANALYZE SELECT id FROM backup_studi.t_archivi WHERE nome = 'dati 
studi' AND creato_il > TO_DATE('2019-05-01', 'DD-MM-YYYY');
"Seq Scan on t_archivi  (cost=0.00..234306.51 rows=1225322 width=8) (actual 
time=0.024..1239.078 rows=1241036 loops=1)"
"  Filter: (((nome)::text = 'dati studi'::text) AND (creato_il > 
to_date('2019-05-01'::text, 'DD-MM-YYYY'::text)))"
"Total runtime: 1277.901 ms"

nome e nome_rep sono rispettivamente varchar(50) e varchar(64) quindi molto 
simili fra loro, su entrambi i campi ho aggiunto la stessa tipologia di 
indice:

CREATE INDEX t_archivi_nome_idx
  ON backup_studi.t_archivi
  USING btree
  (nome COLLATE pg_catalog."default");
CREATE INDEX t_archivi_nome_rep_idx
  ON backup_studi.t_archivi
  USING btree
  (nome_rep COLLATE pg_catalog."default");

E finalmente il domandone: perché sul campo nome viene utilizzato un sequence 
scan con conseguente allungamento dei tempi di interrogazione mentre sul 
campo nome_rep un index scan?

Grazie

Piviul


Other related posts: