Ho una tabella semplice con la colonna singola CHIAVE PRIMARIA chiamata id, digitare serial
. Ci sono esattamente 100.000.000 di file. La tabella accetta 48 GB, indice PK ca 2,1 GB. Il funzionamento della macchina è "dedicato" solo per Postgres ed è simile a Core i5, HDD da 500 GB, 8 GB di RAM. Pg config è stato creato dall'utilità pgtune (buffer condivisi ca 2 GB, cache effettiva ca 7 GB). OS è il server Ubuntu 14.04, Postgres 9.3.6.Perché sia il conteggio SELECT (PK) che il conteggio SELECT (*) sono così lenti?
Perché entrambi sono SELECT count(id)
e SELECT count(*)
così lento in questo semplice caso (circa 11 minuti)?
Perché il planner PostgreSQL sceglie la scansione completa della tabella anziché la scansione dell'indice, che dovrebbe essere almeno 25 volte più veloce (nel caso in cui debba leggere l'intero indice dall'HDD). O dove sbaglio?
Btw eseguire la query più volte di seguito non modifica nulla. ancora cca 11 minuti.
Piano di esecuzione qui:
Aggregate (cost=7500001.00..7500001.01 rows=1 width=0) (actual time=698316.978..698316.979 rows=1 loops=1)
Buffers: shared hit=192 read=6249809
-> Seq Scan on transaction (cost=0.00..7250001.00 rows=100000000 width=0) (actual time=0.009..680594.049 rows=100000001 loops=1)
Buffers: shared hit=192 read=6249809
Total runtime: 698317.044 ms
La quantità di dati da leggere è 25 volte più piccola e contiene tutte le chiavi che è sufficiente per contare, non lo è/non è vero? Ho eseguito sia VACUUM PIENO che ANALIZZA (che ha preso insieme più di 6 ore). – Kousalik
Hai un sacco di DML simultaneo che si sta verificando su quel tavolo? L'indice può (e sarà) utilizzato solo se è affidabile. Se ci sono molte transazioni concorrenti (o transazioni non completate), Postgres potrebbe non scegliere di usare l'indice. Hai una connessione "idle in transaction" che ha modificato quella tabella? Inoltre, qual è il valore di 'random_page_cost' (http://www.postgresql.org/docs/current/static/runtime-config-query.html#GUC-RANDOM-PAGE-COST) tale impostazione influenzerà la tendenza dei pianificatori a usa un indice –
Si potrebbe anche voler leggere questo: https://wiki.postgresql.org/wiki/Index-only_scans –