Ho provato a COUNT(*)
una tabella con 150.000 righe con una chiave primaria. Strumento di circa 5 minuti, quindi ho capito che questo è un problema di indicizzazione.
Citando il manuale PostgreSQL :
REINDEX è simile a una goccia e ricrea l'indice in quanto i contenuti dell'indice vengono ricostruiti da zero. Tuttavia, le considerazioni sul blocco sono piuttosto diverse. REINDEX blocca le scritture ma non le letture della tabella padre dell'indice. Richiede anche un blocco esclusivo sull'indice specifico in fase di elaborazione, che bloccherà le letture che tentano di utilizzare quell'indice (...) Il successivo CREATE INDEX blocca le scritture ma non le letture; poiché l'indice non è presente, nessuna lettura tenterà di utilizzarlo, il che significa che non ci saranno blocchi ma le letture potrebbero essere forzate in costose scansioni sequenziali.
Dalla tua esperienza, puoi dire:
- è
REINDEXING
pericoloso? Può danneggiare la coerenza dei dati? - Può volerci molto tempo?
- È una soluzione probabile al mio scenario?
Aggiornare:
La soluzione che ha funzionato per noi è stata ricreare lo stesso indice con un nome diverso, quindi eliminare il vecchio indice.
La creazione dell'indice è molto rapida e abbiamo ridotto le dimensioni dell'indice da 650 MB a 8 MB. L'uso di COUNT(*)
a between
richiede solo 3 secondi.
COUNT(*)
è la scelta migliore:If you are using count(*), the database is free to use any column to count, which means it can pick the smallest covering index to scan (note that this is why count(*) is much better than count(some_field), as long as you don't care if null values of some_field are counted). Since indexes often fit entirely in memory, this means count(*) is often very fast.