Částečný index je dobrý nápad vyloučit polovinu řádků tabulky, kterou evidentně nepotřebujete. Jednodušší:
CREATE INDEX name_idx ON table (text_col)
WHERE text_col IS NOT NULL;
Nezapomeňte spustit ANALYZE table
po vytvoření indexu. (Autovakuum to po nějaké době udělá automaticky, pokud to neprovedete ručně, ale pokud testujete hned po vytvoření, váš test selže.)
Poté, abyste přesvědčili plánovač dotazů, že lze použít konkrétní částečný index, opakujte WHERE
podmínka v dotazu – i když se zdá být zcela nadbytečná:
SELECT col1,col2, .. colN
FROM table
WHERE text_col = 'my_value'
AND text_col IS NOT NULL; -- repeat condition
Voilá.
Podle dokumentace:
Mějte však na paměti, že predikát musí odpovídat podmínkám použitým v dotazech, které mají mít z indexu prospěch. Abychom byli přesní, částečný index lze v dotazu použít pouze v případě, že systém dokáže rozpoznat, že
WHERE
podmínka dotazu matematicky implikuje predikát indexu. PostgreSQL nemá sofistikovaný dokazovač teorémů, který by dokázal rozpoznat matematicky ekvivalentní výrazy zapsané v různých formách. (Nejen, že se takový obecný teorém ukazuje extrémně obtížně vytvořit, byl by pravděpodobně příliš pomalý na to, aby mohl být skutečně použitelný.) Systém dokáže rozpoznat jednoduché implikace nerovnosti, například "x <1" implikuje "x <2", jinak predikát podmínka musí přesně odpovídat částiWHERE
v dotazu nebo index nebude rozpoznán jako použitelný. Porovnání probíhá v době plánování dotazu, nikoli v době běhu. V důsledku toho klauzule parametrizovaného dotazu nefungují s částečným indexem.
Pokud jde o parametrizované dotazy:opět přidejte (nadbytečný) predikát částečného indexu jako další konstantní WHERE
stavu a funguje dobře.
Důležitá aktualizace v Postgres 9.6 výrazně zvyšuje šance na prověřování pouze pomocí indexu (což může zlevnit dotazy a plánovač dotazů takové plány dotazů snadněji vybere). Související:
- PostgreSQL nepoužívá index během count(*)