2014-11-06 34 views
1

如下所示,我的表A和B之間有一個簡單的連接。另外,每個表上都有一個條件與Or運算符結合使用。oracle不使用定義的索引

SELECT /*+ NO_EXPAND */ 
    * FROM IIndustrialCaseHistory B , 
      IIndustrialCaseProduct A 
    where (
            A.ProductId IN ('9_2') OR 
            contains(B.KeyWords,'%some text goes here%') <=0 

      ) 
     and (B.Id = A.IIndustrialCaseHistoryId) 

在ProductId上定義了一個b-tree索引,而對於KeyWords則有一個函數索引。 但我不知道爲什麼我的執行計劃不使用這些索引,並執行表訪問完整? 正如我在this中找到的那樣,URL NO_EXPAND優化提示可能會在執行計劃中使用索引(NO_EXPAND提示阻止基於成本的優化程序針對WHERE子句中具有OR條件或IN列表的查詢考慮OR-擴展)。但我沒有看到任何使用定義的索引

什麼是與我的查詢的oracle問題?

+1

沒有任何數據或模式,這是很難說。索引是如何定義的以及它們的選擇性如何? (即這些索引匹配的錶行的比例是多少?)您的統計信息是最新的?是否使用了任何索引?也許顯示執行計劃是有用的,有沒有提示。 – 2014-11-06 16:21:26

+0

「B.Id」和「A.IIndustrialCaseHistoryId」上有索引嗎?如果是,那麼查詢是否在執行計劃中使用其中的一個? OR-擴展可用於OR組合兩個引用同一個表的列**的情況,OR中的問題將不同表(連接)的列組合起來,因此在這種情況下NO_EXPAND提示是無用的,因爲Oracle不考慮OR擴展轉換。 – krokodilko 2014-11-06 19:08:22

+0

是的,B.Id是B和A.A.IndustrialCaseHistoryId的主鍵,是指B.Id的外鍵,它們都有索引。但在我的計劃中,只有2個表訪問完整!謝謝,但您能否爲您的關於OR-Expansion的句子提供參考? – Hamed 2014-11-06 19:42:27

回答

0

除非我不知道有關contains()函數的神奇功能,否則Oracle不能使用索引來查找帶有通配符的匹配值,即varchar2列中的文本字符串值,但不能從具有該價值的第一個位置開始。 [或B.KeyWords LIKE'%some some text goes here%' - 而不是 - 或者B .KeyWords LIKE'某些文本從這裏開始%' - 通過索引優化。]優化器將默認回到全表掃描在這種情況下。 此外,雖然它可能不是重要的,但如果列表中只有一個值,爲什麼還要使用IN()?爲什麼不A.ProductId ='9_2'?

+0

據我所知與contains()和IN沒有關係。我用一個簡單的平等條件替換了contains()和IN。但我的執行計劃沒有任何變化 – Hamed 2014-11-07 03:19:35

+0

*有*關於允許左側通配符的contains()函數的神奇功能。 Oracle Text很複雜並且改變了一切。請參閱[這個答案](http://stackoverflow.com/a/6650496/409172)爲例。 – 2014-11-07 06:05:12