Nejprve se ujistím, že správně rozumím otázce:
- Chcete urychlit
SELECT .. WHERE C_D IS NULL
ale vy ne chcete urychlit všechny dotazy, které hledají C_D bez NULL. - Chcete se také ujistit, že v indexu nejsou žádné "zbytečné" hodnoty jiné než NULL, abyste ušetřili místo.
Pokud je toto pochopení správné, pak potřebujete funkční index. Tj. index funkce na poli, nikoli pole samotné...
CREATE INDEX T_IE1 ON T (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) COMPRESS
...který byste pak dotazovali jako...
SELECT * FROM T WHERE (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1
...což je ekvivalentní...
SELECT * FROM T WHERE C_D IS NULL
...ale rychlejší, protože používá index:
To šetří místo, protože indexy s jedním sloupcem neukládají hodnoty NULL. Také použijte COMPRESS
protože index bude vždy obsahovat pouze jeden klíč, takže není třeba plýtvat místem opakováním stejného klíče znovu a znovu ve struktuře indexu.
POZNÁMKA:V systému Oracle 11 můžete také vytvořit funkční virtuální sloupec (na základě CASE
výraz výše), pak indexujte a dotazujte se přímo na tento sloupec, abyste ušetřili některé opakované psaní.
--- UPRAVIT ---
Pokud máte také zájem dotazovat se na C_I společně s C_D IS NULL
, můžete...
CREATE UNIQUE INDEX T_IE2 ON T (C_I, CASE WHEN C_D IS NULL THEN 1 ELSE NULL END)
...a zeptejte se jej pomocí (například)...
SELECT * FROM T WHERE C_I > 'some value' AND (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1
...což je ekvivalentní...
SELECT * FROM T WHERE C_I > 'some value' AND C_D IS NULL
...ale rychleji, protože používá index T_IE2
.
Toto je ve skutečnosti jediný index, který potřebujete na svém stole ("pokrývá" primární klíč, takže už nepotřebujete samostatný index pouze na C_I). Což také znamená, že stejné ROWID nejsou nikdy uloženy ve více než jednom indexu, což šetří místo.
POZNÁMKA:COMPRESS
již nedává smysl pro index T_IE2
.
--- UPRAVIT 2 ---
Pokud vám záleží na jednoduchosti více než na prostoru, stačí vytvořit složený index na {C_I, C_D}. Oracle ukládá hodnoty NULL do složeného indexu, pokud je ve stejné n-tice alespoň jedna hodnota jiná než NULL:
CREATE UNIQUE INDEX T_IE3 ON T (C_I, C_D)
Toto používá index:
SELECT * FROM T WHERE C_I > 1 AND C_D IS NULL
Stejně jako v předchozím EDITu je toto jediný index, který potřebujete na stole.