sql >> Database teknologi >  >> RDS >> Oracle

Oracle 11 Indeks kun for en del af dataene

Lad mig først sikre mig, at jeg forstår spørgsmålet korrekt:

  • Du vil fremskynde SELECT .. WHERE C_D IS NULL men det gør du ikke ønsker at fremskynde enhver af de forespørgsler, der søger efter en ikke-NULL C_D.
  • Du vil også sikre dig, at der ikke er "unødvendige" ikke-NULL-værdier i indekset for at spare plads.

Hvis denne forståelse er korrekt, så har du brug for en funktionel indeks. jeg e. et indeks på en funktion på et felt, ikke et felt i sig selv...

CREATE INDEX T_IE1 ON T (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) COMPRESS

...som du så ville forespørge som...

SELECT * FROM T WHERE (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1

...hvilket svarer til...

SELECT * FROM T WHERE C_D IS NULL

...men hurtigere, da den bruger indekset:

Dette sparer plads, fordi enkeltkolonneindekser ikke gemmer NULL'er. Brug også COMPRESS da indeks nogensinde kun vil indeholde én nøgle, så der er ingen grund til at spilde plads på at gentage den samme nøgle igen og igen i indeksstrukturen.

BEMÆRK:Under Oracle 11 kan du også oprette en funktionsbaseret virtuel kolonne (baseret på CASE udtryk ovenfor), indeksér og forespørg derefter på den kolonne direkte for at gemme nogle gentagne indtastninger.

--- REDIGER ---

Hvis du også er interesseret i at forespørge på C_I sammen med C_D IS NULL , du kunne...

CREATE UNIQUE INDEX T_IE2 ON T (C_I, CASE WHEN C_D IS NULL THEN 1 ELSE NULL END)

...og forespørg det med (for eksempel)...

SELECT * FROM T WHERE C_I > 'some value' AND (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1

...hvilket svarer til...

SELECT * FROM T WHERE C_I > 'some value' AND C_D IS NULL

...men hurtigere, da den bruger indekset T_IE2 .

Dette er faktisk det eneste indeks, du har brug for på din tabel (det "dækker" primærnøglen, så du behøver ikke længere et separat indeks kun på C_I). Hvilket også betyder, at de samme ROWID'er aldrig gemmes i mere end ét indeks, hvilket sparer plads.

BEMÆRK:COMPRESS giver ikke længere mening for indeks T_IE2 .

--- EDIT 2 ---

Hvis du interesserer dig mere for enkelhed end plads, kan du bare oprette et sammensat indeks på {C_I, C_D}. Oracle gemmer NULL-værdier i sammensat indeks, så længe der er mindst én ikke-NULL-værdi i samme tuple:

CREATE UNIQUE INDEX T_IE3 ON T (C_I, C_D)

Dette bruger indekset:

SELECT * FROM T WHERE C_I > 1 AND C_D IS NULL

Som i tidligere EDIT er dette det eneste indeks, du har brug for på dit bord.



  1. postgresql jsonb ufølsom forespørgsel

  2. 4 datatyper, der skal udfases i SQL Server

  3. Bliv tændt af Apache Spark – Del 2

  4. Postgresql, opdatering eller indsæt baseret på sag