In generale, col IS NULL
è un possibile candidato per una ricerca (predefinita) dell'indice b-tree. Il manuale :
Inoltre, una condizione IS NULL
o IS NOT NULL
su una colonna di indice può essere utilizzata con un indice B-tree.
Per ottenere la prova, disabilita le scansioni sequenziali (solo in una sessione di test!):
SET enable_seqscan = OFF;
Cito il manuale qui :
enable_seqscan (boolean)
Abilita o disabilita l'uso del pianificatore di query di tipi di piano di scansione sequenziale. È impossibile sopprimere completamente le scansioni sequenziali, ma la disattivazione di questa variabile scoraggia il pianificatore dall'utilizzarne una se sono disponibili altri metodi. L'impostazione predefinita è attiva.
Quindi riprovare:
EXPLAIN ANALYZE SELECT * FROM tbl WHERE auto_renew IS NULL;
Ciò comporterà probabilmente una scansione dell'indice bitmap più lenta di una scansione sequenziale sulla tabella.
Ripristina o chiudi la sessione (l'impostazione è session-local).
RESET enable_seqscan;
Gli indici sulle boolean
colonne sono utili solo in alcuni casi. Il pianificatore utilizza un indice solo se si aspetta che sia più veloce. I calcoli si basano sulle impostazioni dei costi e sulle statistiche raccolte da ANALYZE
. Se una parte considerevole della tabella corrisponde alla tua condizione (circa il 5% o più, dipende), in genere è più veloce eseguire una scansione completa della tabella.
Questo lascia il raro valore in una boolean
colonna come unico candidato utile per un indice semplice. Ed è in genere più efficiente creare un indice parziale (più specializzato) per questo, che è più economico da mantenere, più piccolo, più veloce e utilizzato più facilmente se le condizioni della query corrispondono.
Se hai molte query con le quali cerchi delle righe auto_renew IS NULL
e il NULL
caso non è molto comune (e / o hai bisogno di un certo ordinamento), questo indice ti aiuterebbe a trovare / ordinare rapidamente queste righe:
CREATE INDEX index_tbl_tbl_id_auto_renew_null ON tbl (tbl_id)
WHERE auto_renew IS NULL;
La condizione dell'indice parziale deve essere ripetuta WHERE
più o meno esattamente nella clausola di una query per fare in modo che il pianificatore di query realizzi che l'indice è applicabile.
La colonna indicizzata ( tbl_id
) è una scelta arbitraria. La parte importante è la WHERE
clausola. Questo particolare indice sarebbe più efficace per le query con ORDER BY tbl_id
o un filtro aggiuntivo o su cui partecipare tbl_id
. Potresti renderlo un indice a più colonne . Le colonne booleane sono spesso più utili in combinazione con altre.
A parte: gli ORM sono stampelle che non riescono regolarmente a sfruttare appieno il tuo RDBMS.