Een gedeeltelijke index is een goed idee om de helft van de rijen van de tabel uit te sluiten die u uiteraard niet nodig heeft. Eenvoudiger:
CREATE INDEX name_idx ON table (text_col)
WHERE text_col IS NOT NULL;
Zorg ervoor dat u ANALYZE table
uitvoert na het maken van de index. (Autovacuum doet dat na enige tijd automatisch als je het niet handmatig doet, maar als je direct na het maken test, zal je test mislukken.)
Om de queryplanner ervan te overtuigen dat een bepaalde gedeeltelijke index kan worden gebruikt, herhaalt u vervolgens de WHERE
voorwaarde in de zoekopdracht - zelfs als deze volledig overbodig lijkt:
SELECT col1,col2, .. colN
FROM table
WHERE text_col = 'my_value'
AND text_col IS NOT NULL; -- repeat condition
Voilá.
Per documentatie:
Houd er echter rekening mee dat het predikaat moet overeenkomen met de voorwaarden die worden gebruikt in de query's die verondersteld worden te profiteren van de index. Om precies te zijn, een gedeeltelijke index kan alleen in een zoekopdracht worden gebruikt als het systeem kan herkennen dat de
WHERE
voorwaarde van de vraag wiskundig impliceert het predikaat van de index. PostgreSQL heeft geen geavanceerde stellingbewijzer die wiskundig equivalente uitdrukkingen kan herkennen die in verschillende vormen zijn geschreven. (Niet alleen is zo'n algemene stellingbewijzer buitengewoon moeilijk te maken, het zou waarschijnlijk te langzaam zijn om van enig nut te zijn.) Het systeem kan eenvoudige implicaties voor ongelijkheid herkennen, bijvoorbeeld "x <1" impliceert "x <2"; anders zou het predikaat voorwaarde moet exact overeenkomen met een deel van deWHERE
. van de query voorwaarde of de index wordt niet herkend als bruikbaar. Matching vindt plaats tijdens het plannen van de query, niet tijdens runtime. Als gevolg hiervan werken geparametriseerde query-clausules niet met een gedeeltelijke index.
Wat betreft geparametriseerde zoekopdrachten:voeg opnieuw het (redundante) predikaat van de gedeeltelijke index toe als een extra, constante WHERE
staat, en het werkt prima.
Een belangrijke update in Postgres 9.6 verbetert grotendeels de kansen voor index-only scans (waardoor query's goedkoper kunnen worden en de queryplanner gemakkelijker dergelijke queryplannen zal kiezen). Gerelateerd:
- PostgreSQL gebruikt index niet tijdens telling(*)