2012-01-27 59 views
-1

我已經做了一些搜索,但我更喜歡像一個提示或類似甲骨文:使用索引搜索空值

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

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

+5

有什麼問題嗎? – Gerrat 2012-01-27 16:34:23

+3

@ Gik25 - 我不確定我是否理解這個問題。如果您爲單個列建立索引,Oracle b-tree索引不會索引NULL值。查詢中的提示無法影響索引中的行。正如您發現的那樣,創建可以索引NULL值的索引的方法有多種,但這需要創建索引,並考慮搜索NULL值。 – 2012-01-27 16:36:07

+0

有興趣引用的列中有多少個不同的值?位圖索引確實存儲了空值,但是它們具有自己的性能特徵和怪癖,因此它們不是BTree索引的直接替代品。 – 2012-01-31 14:57:04

回答

1

如果您問「如何創建一個索引,以便在特定字段上搜索NULL值時使用該索引」,我的建議是在您感興趣的字段上創建一個索引加主鍵字段。因此,如果你有一個名爲A_TABLE的表,帶有你想搜索NULL的字段VAL和一個名爲PK的主鍵,我會在(VAL,PK)上創建一個索引。

分享和享受。

1

我要「答案」非 - 以上問題。

您鏈接的文章有點兒不對 - Oracle的b-tree索引在葉節點爲空時不會捕獲。就拿這個例子:

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,並損害了表中的數據。戈爾巴喬夫的方法包括一個已知的NOT NULL列的樹的樹葉,但這無緣無故擴大索引。也許在他的情況下,索引對於調整其他查詢是有意義的,但是如果你想要做的只是找到NULL,那麼最簡單的解決方案就是讓葉子保持不變。

CREATE INDEX MYTABLE_IDX_1 ON MYTABLE (DAT, 1); 

現在,葉子都是恆定的(1),默認情況下的空都將一起(無論是在頂部或指數的底部,但它其實並不重要,因爲可以使用Oracle該指數向前或向後)。這個常數存在輕微的存儲損失,但是單個數字比典型表中的大多數其他數據字段要小。現在數據庫可以在查詢空值時使用索引......如果優化器找到獲取數據的最佳方式。

+0

我對索引中第二個字段使用常量的擔心是,它可能會導致DELETE過程緩慢,因爲可能會按順序搜索所有重複項。我在其他數據庫產品中遇到過問題 - 不確定這是否是Oracle的問題。 – 2012-01-27 17:45:27

+0

索引將始終(幕後)將創建索引條目的記錄的ROWID存儲爲最後一個「列」。也就是說,數據庫不需要順序遍歷索引中的所有(NULL,1)條目,因爲ROWID也包含在排序中。 – 2012-01-27 18:02:57

+0

很高興知道 - 謝謝! – 2012-01-27 18:05:58

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