PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL non utilizza un indice parziale

Un indice parziale è una buona idea per escludere metà delle righe della tabella che ovviamente non servono. Più semplice:

CREATE INDEX name_idx ON table (text_col)
WHERE text_col IS NOT NULL;

Assicurati di eseguire ANALYZE table dopo aver creato l'indice. (Autovacuum lo fa automaticamente dopo un po' di tempo se non lo fai manualmente, ma se esegui il test subito dopo la creazione, il test fallirà.)

Quindi, per convincere il pianificatore di query che è possibile utilizzare un particolare indice parziale, ripetere il WHERE condizione nella query, anche se sembra completamente ridondante:

SELECT col1,col2, .. colN
FROM   table 
WHERE  text_col = 'my_value'
AND   text_col IS NOT NULL;  -- repeat condition

Voilà.

Per documentazione:

Tuttavia, tieni presente che il predicato deve corrispondere alle condizioni utilizzate nelle query che dovrebbero trarre vantaggio dall'indice. Per essere precisi, un indice parziale può essere utilizzato in una query solo se il sistema è in grado di riconoscere che il WHERE condizione della query implica matematicamente il predicato dell'indice. PostgreSQL non ha un sofisticato dimostratore di teoremi in grado di riconoscere espressioni matematicamente equivalenti che sono scritte in forme diverse. (Non solo un tale teorema generale è estremamente difficile da creare, ma sarebbe probabilmente troppo lento per essere di qualsiasi utilità reale.) Il sistema può riconoscere semplici implicazioni di disuguaglianza, ad esempio "x <1" implica "x <2"; altrimenti il ​​predicato la condizione deve corrispondere esattamente a parte del WHERE della query condizione o l'indice non verrà riconosciuto come utilizzabile. La corrispondenza avviene in fase di pianificazione della query, non in fase di esecuzione. Di conseguenza, le clausole di query parametrizzate non funzionano con un indice parziale.

Per quanto riguarda le query parametrizzate:aggiungi ancora il predicato (ridondante) dell'indice parziale come costante aggiuntiva WHERE condizione e funziona perfettamente.

Un importante aggiornamento in Postgres 9.6 migliora notevolmente le possibilità di scansioni solo indice (che può rendere le query più economiche e il pianificatore di query sceglierà più prontamente tali piani di query). Correlati:

  • PostgreSQL non utilizza l'indice durante il conteggio(*)