2012-01-27 6 views
-1

を検索するためのインデックスを使用し、私はいくつかの検索を行ってきたが、私は「答え」非つもりヒントまたは類似の:null値

http://www.dba-oracle.com/oracle_tips_null_idx.htm

http://www.oracloid.com/2006/05/using-index-for-is-null/

+5

質問がここにありあなたを与える必要がありますか? – Gerrat

+3

@ Gik25 - 私はその質問を理解しているかどうかはわかりません。単一の列を索引付けする場合、Oracleのbツリー索引はNULL値を索引付けしません。問合せのヒントは、索引に含まれる行に影響を与えることはできません。見つけたようにNULL値を索引付けできる索引を作成するにはさまざまな方法がありますが、NULL値を念頭に置いて索引を作成する必要があります。 –

+0

参照する列のいくつの異なる値がありますか?ビットマップ索引はヌルを格納しますが、独自のパフォーマンス特性と癖があり、BTree索引のドロップイン置換ではありません。 –

答えて

1

あなたは私の提案は、あなたが興味を持っているフィールドにインデックスを作成することである、「どのように私は特定のフィールドにNULL値を検索するときに、それを使用することができるようになるインデックスを作成することができます」、求めている場合プライマリキーフィールドを追加します。したがって、フィールドVALとNULLを検索するA_TABLEというテーブルと、PKという名前のプライマリキーがある場合は、(VAL、PK)のインデックスを作成します。

共有して楽しんでください。

1

のようなものを好みます上記の質問。あなたがにリンク

記事はちょっと右にある - リーフノードがnullのときにOracleのBツリーインデックスはキャプチャされません。この例を見てみましょう:葉(一番右の列は)ヌルをキャプチャしませんので、

CREATE TABLE MYTABLE (
    ID NUMBER(8) NOT NULL, 
    DAT VARCHAR2(100) 
); 

CREATE INDEX MYTABLE_IDX_1 ON MYTABLE (DAT); 

/* Perform inserts into MYTABLE where some DAT are null */ 

SELECT COUNT(*) FROM MYTABLE WHERE DAT IS NULL; 

終了SELECTは、インデックスを使用することはできません。 Burlesonのソリューションは、すべてのクエリでNVLを使用しなければならず、テーブルのデータが侵害されてしまったため、愚かです。ゴルバチョフの方法は、Bツリーの葉のための既知のNOT NULL列が含まれていますが、これは理由もなくインデックスを展開します。たぶん、彼の場合にはインデックスが意味チューニング他のクエリのためにそのように作られた、しかし、あなたがしたいすべてがNULLのを見つけているならば、最も簡単な解決策は、葉を一定にすることです。

CREATE INDEX MYTABLE_IDX_1 ON MYTABLE (DAT, 1); 

は今、葉は、(1)すべての定数であり、デフォルトでヌルがすべてのいずれかの上部またはインデックスの一番下に(一緒になりますが、Oracleが使用できるよう、それは本当に問題ではありません。インデックスは前方または後方に)。その定数にはわずかなストレージペナルティがありますが、単一の数値は通常の表のほとんどの他のデータフィールドよりも小さくなります。オプティマイザがデータを取得する最適な方法を見つけたら、データベースはNULLをクエリするときにインデックスを使用できます。

+0

インデックス内の2番目のフィールドのための定数を使用して私の懸念は、すべての重複が順次検索される可能性があるとして、それはDELETEの間に遅さを引き起こす可能性があるということです。私は他のデータベース製品に問題を抱えていました.Oracleにとって問題なのかどうかは不明です。 –

+0

索引は、常に最後の「列」としてその索引項目を作成したレコードのROWIDを保管します(背後に)。つまり、ROWIDもソートに含まれているため、索引内のすべての(NULL、1)エントリを順番に処理する必要はありません。 –

+0

お気軽にお問い合わせください - ありがとう! –

2

NVL2を使用して、機能指標について何、等。

CREATE TABLE foo (bar INTEGER); 
INSERT INTO foo VALUES (1); 
INSERT INTO foo VALUES (NULL); 
CREATE INDEX baz ON foo (NVL2(bar,0,1)); 

です。

DELETE plan_table; 
EXPLAIN PLAN FOR SELECT * FROM foo WHERE NVL2(bar,0,1) = 1; 
SELECT operation, object_name FROM plan_table; 

OPERATION  OBJECT_NAME 
---------------- ----------- 
SELECT STATEMENT 
TABLE ACCESS  FOO 
INDEX   BAZ  << yep