PostgreSQL: COUNT (*) utilizza una scansione sequenziale, non un indice


12

Perché PostgreSQL esegue la scansione sequenziale della tabella alla COUNT(*)ricerca di query, mentre esiste una chiave primaria molto piccola e indicizzata?

Risposte:


15

Le pagine wiki ufficiali danno una risposta a questo:

[...] Il motivo per cui questo è lento è legato all'implementazione MVCC in PostgreSQL. Il fatto che più transazioni possano vedere diversi stati dei dati significa che non ci può essere un modo semplice per "COUNT (*)" per riassumere i dati nell'intera tabella; PostgreSQL deve attraversare tutte le righe, in un certo senso. Ciò si traduce normalmente in una scansione sequenziale che legge le informazioni su ogni riga della tabella. [...]

Inoltre, è possibile provare un ANALYZE per ricostruire le informazioni per il piano di query.

Dovresti ottenere prestazioni migliori utilizzando, COUNT(an uniquly indexed field)ma se questo è molto grande, una scansione seq è l'unico modo per farlo.

Se hai bisogno di numeri molto rapidi e non hai paura di interrogare lo schema, puoi fare quanto segue

SELECT reltuples FROM pg_class WHERE oid = 'your_table'::regclass

Ma non fare affidamento su questi valori in quanto è solo un numero "stimato" (sebbene spesso esatto) di tuple nella tabella.


Non penso sia corretto. Non ho letto nulla da nessuna parte, dove COUNT(pk)migliorerà le prestazioni. Penso che farà sempre una scansione seq
vol7ron

1
Senza una clausola where corretta, verrà eseguita una scansione seq. Con una clausola sufficientemente selezionata su dove postgresql PU use usare un indice, ma tieni presente che tornerà alla tabella per verificare la visibilità delle tuple su cui sta riferendo.
Scott Marlowe,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.