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

PostgreSQL bruger ikke et delvist indeks

Et delvis indeks er en god idé at udelukke halvdelen af ​​tabellens rækker, som du åbenbart ikke har brug for. Enklere:

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

Sørg for at køre ANALYZE table efter oprettelse af indekset. (Autovacuum gør det automatisk efter et stykke tid, hvis du ikke gør det manuelt, men hvis du tester lige efter oprettelsen, vil din test mislykkes.)

Gentag derefter WHERE for at overbevise forespørgselsplanlæggeren om, at et bestemt delvist indeks kan bruges. betingelse i forespørgslen - også selvom den virker helt overflødig:

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

Voilá.

Per dokumentation:

Husk dog, at prædikatet skal matche de betingelser, der bruges i de forespørgsler, der formodes at have gavn af indekset. For at være præcis kan et delvist indeks kun bruges i en forespørgsel, hvis systemet kan genkende, at WHERE betingelse for forespørgslen indebærer matematisk prædikatet for indekset. PostgreSQL har ikke en sofistikeret teorembeviser, der kan genkende matematisk ækvivalente udtryk, der er skrevet i forskellige former. (Ikke alene er sådan en generel sætning bevist ekstremt vanskelig at skabe, den ville sandsynligvis være for langsom til at være til nogen reel nytte.) Systemet kan genkende simple ulighedsimplikationer, for eksempel "x <1" betyder "x <2"; ellers prædikatet betingelse skal nøjagtigt matche en del af forespørgslens WHERE betingelse, eller indekset vil ikke blive genkendt som brugbart. Matching finder sted på forespørgselsplanlægningstidspunktet, ikke på kørselstidspunktet. Som følge heraf virker parametriserede forespørgselsklausuler ikke med et delvist indeks.

Med hensyn til parametriserede forespørgsler:igen, tilføj det (redundante) prædikat for det partielle indeks som en ekstra konstant WHERE stand, og det fungerer fint.

En vigtig opdatering i Postgres 9.6 forbedrer i høj grad chancerne for kun-indeksscanninger (hvilket kan gøre forespørgsler billigere, og forespørgselsplanlæggeren vil lettere vælge sådanne forespørgselsplaner). Relateret:

  • PostgreSQL bruger ikke indeks under optælling(*)


  1. mysqli eller PDO - hvad er fordele og ulemper?

  2. Vores nye SQLPerformance.com nyhedsbrev

  3. To kolonner i underforespørgsel i where-klausul

  4. Saml kolonner med yderligere (særskilte) filtre