Ciao, secondo me succede questo:
Nel primo caso usa l'algoritmo di Nested Loop per il join, che
generalmente e' il piu' scarso come performance, ma che ottiene buoni
risultati grazie all'indice sull'inner table (Index Scan using
idx_rilev on dettagliorilevamenti dr). Inoltre, da bravo query
optimizer, ti fa anche il push della selezione. Quindi la prima query
va veloce perche' e' ottimizzata al meglio.
La seconda query invece e' abbastanza chiara ma dovrai rispondere a
una domanda dopo per capire perche' scegli questo query plan. In
pratica nella seconda query lui sceglie il Merge Join che teoricamente
e' superiore nelle performance MA a una condizione: gli attributi su
cui fai il join devono essere preordinati o indicizzati, altrimenti lo
fa postgresql il sort, che ha un costo elevatissimo e che ti fa andare
peggio di un Nested Loop. E uno dei due non e' indicizzato. Ti faccio
il commento riga per riga:
-> Merge Join (cost=1869.01..829123.45 rows=306454 width=0)
Merge Cond: ("outer".id_rilev = "inner".id)
-> Index Scan using idx_rilev on dettagliorilevamenti dr
(cost=0.00..767437.41 rows=22245028 width=4)
-> Sort (cost=1869.01..1876.54 rows=3015 width=8)
Sort Key: r.id
-> Index Scan using idx_data on rilevamenti r
(cost=0.00..1694.77 rows=3015 width=8)
Index Cond: ((datain >= '2007-12-01
00:00:00'::timestamp without time zone) AND (datain <= '2007-12-12
00:00:00'::timestamp without time zone))
ciao a tutti,
sto facendo esperimenti di performance con Postgres per eventualmente
portare un DB da MS SQL server a PostgreSQL.
Ho importato in Postgres le due tabelle più 'corpose':
'rilevamenti' da 220000 record circa e
'dettagliorilevamenti' da 22 milioni di record circa.
Quando eseguo la seguente query il tempo impiegato è accettabile (e
molto breve dal secondo run):
explain select count(*) as N
from rilevamenti r
inner join dettagliorilevamenti dr on r.id=dr.id_rilev
where r.datain between '2007-12-01' and '2007-12-11'
Aggregate (cost=821350.49..821350.50 rows=1 width=0)
-> Nested Loop (cost=0.00..820653.98 rows=278604 width=0)
-> Index Scan using idx_data on rilevamenti r
(cost=0.00..1546.23 rows=2741 width=8)
Index Cond: ((datain >= '2007-12-01 00:00:00'::timestamp
without time zone) AND (datain <= '2007-12-11 00:00:00'::timestamp
without time zone))
-> Index Scan using idx_rilev on dettagliorilevamenti dr
(cost=0.00..224.01 rows=5986 width=4)
Index Cond: ("outer".id = dr.id_rilev)
se aggiungo un giorno nella query (come data finale chiedo '2007-12-12')
il tempo di esecuzione esplode (e non migliora nei run successivi) e il
query plan diventa:
Aggregate (cost=829889.59..829889.60 rows=1 width=0)
-> Merge Join (cost=1869.01..829123.45 rows=306454 width=0)
Merge Cond: ("outer".id_rilev = "inner".id)
-> Index Scan using idx_rilev on dettagliorilevamenti dr
(cost=0.00..767437.41 rows=22245028 width=4)
-> Sort (cost=1869.01..1876.54 rows=3015 width=8)
Sort Key: r.id
-> Index Scan using idx_data on rilevamenti r
(cost=0.00..1694.77 rows=3015 width=8)
Index Cond: ((datain >= '2007-12-01
00:00:00'::timestamp without time zone) AND (datain <= '2007-12-12
00:00:00'::timestamp without time zone))
qualcuno potrebbe indicarmi quale strada potrei intraprendere per
cercare di risolvere il problema?
grazie e ciao
riki