sql >> Database >  >> RDS >> Oracle

Oracle 11 Index alleen voor een deel van de gegevens

Laat me eerst controleren of ik de vraag goed begrijp:

  • U wilt versnellen SELECT .. WHERE C_D IS NULL maar jij doet niet alle zoekopdrachten die zoeken naar een niet-NULL C_D wilt versnellen.
  • U wilt er ook voor zorgen dat er geen "onnodige" niet-NULL-waarden in de index staan, om ruimte te besparen.

Als dat begrip juist is, dan heb je een functioneel . nodig inhoudsopgave. D.w.z. een index op een functie op een veld, niet een veld zelf...

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

...die je dan zou opvragen als...

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

...wat gelijk is aan...

SELECT * FROM T WHERE C_D IS NULL

...maar sneller omdat het de index gebruikt:

Dit bespaart ruimte omdat indexen met één kolom geen NULL's opslaan. Gebruik ook COMPRESS omdat index altijd maar één sleutel zal bevatten, dus het is niet nodig om ruimte te verspillen aan het steeds opnieuw herhalen van dezelfde sleutel in de indexstructuur.

OPMERKING:onder Oracle 11 kunt u ook een functiegebaseerde virtuele kolom (gebaseerd op de CASE expressie hierboven), indexeer en zoek vervolgens rechtstreeks op die kolom, om wat repetitief typen te besparen.

--- BEWERKEN ---

Als u ook geïnteresseerd bent in het opvragen van C_I samen met C_D IS NULL , je zou...

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

...en vraag ernaar met (bijvoorbeeld)...

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

...wat gelijk is aan...

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

...maar sneller, omdat het de index T_IE2 gebruikt .

Dit is in feite de enige index die je nodig hebt op je tabel (dekt de primaire sleutel, dus je hebt niet langer een aparte index nodig alleen op C_I). Wat ook betekent dat dezelfde ROWID's nooit in meer dan één index worden opgeslagen, wat ruimte bespaart.

OPMERKING:COMPRESS heeft geen zin meer voor index T_IE2 .

--- EDIT 2 ---

Als u meer om eenvoud dan om ruimte geeft, kunt u gewoon een samengestelde index maken op {C_I, C_D}. Oracle slaat NULL-waarden op in samengestelde index zolang er ten minste één niet-NULL-waarde in dezelfde tuple staat:

CREATE UNIQUE INDEX T_IE3 ON T (C_I, C_D)

Dit gebruikt de index:

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

Net als in de vorige EDIT, is dit de enige index die je nodig hebt op je tafel.



  1. Criteria zoeken op basis van TextField en een lijstmenu

  2. eenvoudige sql-query, resultaten combineren en delen

  3. Hoe een SSIS-pakket uit te voeren wanneer een bestand in de map is aangekomen?

  4. Google App Engine Datastore exporteren naar MySQL?