Najpierw upewnię się, że dobrze rozumiem pytanie:
- Chcesz przyspieszyć
SELECT .. WHERE C_D IS NULL
ale nie chcesz przyspieszyć dowolne z zapytań, które wyszukują C_D inne niż NULL. - Chcesz również upewnić się, że w indeksie nie ma „niepotrzebnych” wartości innych niż NULL, aby zaoszczędzić miejsce.
Jeśli to zrozumienie jest poprawne, potrzebujesz funkcjonalnego indeks. Tj. indeks funkcji w polu, a nie samo pole...
CREATE INDEX T_IE1 ON T (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) COMPRESS
...które następnie zapytasz jako...
SELECT * FROM T WHERE (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1
...co jest równoważne...
SELECT * FROM T WHERE C_D IS NULL
...ale szybciej, ponieważ używa indeksu:
Oszczędza to miejsce, ponieważ indeksy jednokolumnowe nie przechowują wartości NULL. Użyj także COMPRESS
ponieważ indeks zawsze będzie zawierał tylko jeden klucz, więc nie ma potrzeby marnowania miejsca na powtarzanie tego samego klucza w strukturze indeksu.
UWAGA:W Oracle 11 można również utworzyć wirtualną kolumnę opartą na funkcjach (na podstawie CASE
wyrażenie powyżej), a następnie zindeksuj i zapytaj bezpośrednio o tę kolumnę, aby zaoszczędzić trochę powtarzającego się pisania.
--- EDYTUJ ---
Jeśli jesteś również zainteresowany zapytaniami na C_I razem z C_D IS NULL
, możesz...
CREATE UNIQUE INDEX T_IE2 ON T (C_I, CASE WHEN C_D IS NULL THEN 1 ELSE NULL END)
...i przeprowadź zapytanie za pomocą (na przykład)...
SELECT * FROM T WHERE C_I > 'some value' AND (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1
...co jest odpowiednikiem...
SELECT * FROM T WHERE C_I > 'some value' AND C_D IS NULL
...ale szybciej, ponieważ używa indeksu T_IE2
.
W rzeczywistości jest to jedyny indeks, którego potrzebujesz na swoim stole (zakrywa on klucz podstawowy, więc nie potrzebujesz już osobnego indeksu tylko na C_I). Co oznacza również, że te same identyfikatory ROWID nigdy nie są przechowywane w więcej niż jednym indeksie, co pozwala zaoszczędzić miejsce.
UWAGA:COMPRESS
nie ma już sensu dla indeksu T_IE2
.
--- EDYCJA 2 ---
Jeśli zależy Ci bardziej na prostocie niż na przestrzeni, możesz po prostu utworzyć indeks złożony na {C_I, C_D}. Oracle przechowuje wartości NULL w indeksie złożonym, o ile w tej samej krotce znajduje się co najmniej jedna wartość różna od NULL:
CREATE UNIQUE INDEX T_IE3 ON T (C_I, C_D)
Używa indeksu:
SELECT * FROM T WHERE C_I > 1 AND C_D IS NULL
Podobnie jak w poprzedniej edycji, jest to jedyny indeks, którego potrzebujesz na swoim stole.