sql >> Databáze >  >> RDS >> PostgreSQL

PostgreSQL nepoužívá částečný index

Čá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 části WHERE 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(*)


  1. Blokovat, blokovat, blokovat na dveřích DBA s blokováním serveru SQL

  2. Odstraňte duplikáty z výsledků Count() v SQLite

  3. Jak mohu získat názvy sloupců z tabulky na serveru SQL?

  4. ORA-12170:TNS:Vypršel časový limit připojení