Нека първо се уверя, че разбирам правилно въпроса:
- Искате да ускорите
SELECT .. WHERE C_D IS NULL
но вие нене искате да ускорите всяка от заявките, които търсят не-NULL C_D. - Също така искате да сте сигурни, че в индекса няма „ненужни“ стойности, различни от NULL, за да спестите място.
Ако това разбиране е правилно, тогава това, от което се нуждаете, е функционален индекс. Аз съм. индекс на функция в поле, а не самото поле...
CREATE INDEX T_IE1 ON T (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) COMPRESS
...което след това ще зададете като...
SELECT * FROM T WHERE (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1
...което е еквивалентно на...
SELECT * FROM T WHERE C_D IS NULL
...но по-бързо, тъй като използва индекса:
Това спестява място, тъй като индексите с една колона не съхраняват NULL. Също така използвайте COMPRESS
тъй като индексът винаги ще съдържа само един ключ, така че няма нужда да губите място за повтаряне на същия ключ отново и отново в структурата на индекса.
ЗАБЕЛЕЖКА:Под Oracle 11 можете също да създадете функционална виртуална колона (въз основа на CASE
израз по-горе), след това индексирайте и заявете директно тази колона, за да спестите част от повтарящото се писане.
--- РЕДАКТИРАНЕ ---
Ако също се интересувате от заявки на C_I заедно с C_D IS NULL
, бихте могли...
CREATE UNIQUE INDEX T_IE2 ON T (C_I, CASE WHEN C_D IS NULL THEN 1 ELSE NULL END)
...и го потърсете с (например)...
SELECT * FROM T WHERE C_I > 'some value' AND (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1
...което е еквивалентно на...
SELECT * FROM T WHERE C_I > 'some value' AND C_D IS NULL
...но по-бързо, тъй като използва индекса T_IE2
.
Това всъщност е единственият индекс, от който се нуждаете във вашата таблица (той "покрива" първичния ключ, така че вече не се нуждаете от отделен индекс само на C_I). Което също означава, че едни и същи ROWID никога не се съхраняват в повече от един индекс, което спестява място.
ЗАБЕЛЕЖКА:COMPRESS
вече няма смисъл за индекс T_IE2
.
--- РЕДАКТИРАНЕ 2 ---
Ако държите на простотата повече от пространството, можете просто да създадете съставен индекс на {C_I, C_D}. Oracle съхранява NULL стойности в съставен индекс, стига да има поне една не-NULL стойност в същия кортеж:
CREATE UNIQUE INDEX T_IE3 ON T (C_I, C_D)
Това използва индекса:
SELECT * FROM T WHERE C_I > 1 AND C_D IS NULL
Както в предишното РЕДАКТИРАНЕ, това е единственият индекс, от който се нуждаете във вашата таблица.