sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL använder inte ett partiellt index

Ett partiellt index är en bra idé att utesluta halva raderna i tabellen som du uppenbarligen inte behöver. Enklare:

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

Var noga med att köra ANALYZE table efter att du har skapat indexet. (Autovacuum gör det automatiskt efter en tid om du inte gör det manuellt, men om du testar direkt efter skapandet kommer ditt test att misslyckas.)

Sedan, för att övertyga frågeplaneraren om att ett visst delindex kan användas, upprepa WHERE villkor i frågan - även om den verkar helt överflödig:

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

Voilá.

Per dokumentation:

Tänk dock på att predikatet måste matcha de villkor som används i de frågor som ska dra nytta av indexet. För att vara exakt kan ett partiellt index endast användas i en fråga om systemet kan känna igen att WHERE villkoret för frågan innebär matematiskt indexets predikat. PostgreSQL har inte ett sofistikerat satsbevis som kan känna igen matematiskt likvärdiga uttryck som är skrivna i olika former. (Inte bara är ett sådant generellt teorem extremt svårt att skapa, det skulle förmodligen vara för långsamt för att vara till någon verklig användning.) Systemet kan känna igen enkla olikhetsimplikationer, till exempel "x <1" innebär "x <2"; annars predikatet villkoret måste exakt matcha en del av frågans WHERE skick eller så kommer indexet inte att kännas igen som användbart. Matchning sker vid frågeplaneringstid, inte vid körning. Som ett resultat fungerar inte parametriserade frågesatser med ett partiellt index.

När det gäller parametriserade frågor:återigen, lägg till det (redundanta) predikatet för det partiella indexet som en ytterligare konstant WHERE skick och det fungerar bra.

En viktig uppdatering i Postgres 9.6 förbättrar till stor del chanserna för endast indexsökningar (vilket kan göra frågor billigare och frågeplaneraren kommer lättare att välja sådana frågeplaner). Relaterat:

  • PostgreSQL använder inte index under count(*)


  1. Django cache.set() orsakar dubblettnyckelfel

  2. Använder parameter som kolumnnamn i Postgres-funktionen

  3. Kombinera två tabeller som inte har några gemensamma fält

  4. SQL-satsen ignorerar where-parametern