2009-06-25 20 views
2

我已經繼承了一個有點混亂的查詢,我正在重構爲高性能。如何判斷在內聯視圖中推送會減慢查詢速度?

在這個過程中,由於個人喜好我所做的一件事是將「內連接」和「左外連接」語句中的所有ANSI-99連接語法都改爲查詢中的謂詞。我注意到了兩件非常奇怪的事情,我會感激解釋。

  1. 更改「INNER JOIN ...」語法中的連接更改了解釋計劃。使用ANSI 99語法,oracle對正在連接的列進行全表掃描。在改變連接語法之後,它現在執行謂詞推送。爲什麼連接語法會改變解釋計劃?
  2. 推進內聯視圖的謂詞實際上減慢了查詢的極大幅度。大約3秒後運行的查詢(在更改連接之前)。現在它需要9秒。說實話,我對閱讀解釋計劃相當陌生,所以完全有可能由於其他原因,查詢的重組放慢了速度。但最終我的問題是:「索引列上的謂詞推送是否有可能大大減慢查詢速度?如果是這樣,爲什麼?」

感謝您的答覆,我的道歉,如果這是不是很清楚......

+0

請在發佈之前和之後的查詢中,您的更改可能不僅僅是「語法」更改 - 如果它們更改查詢的含義(或添加/刪除可用於優化器的信息)該計劃相當大。 – 2009-06-26 01:52:04

回答

3

是否有可能推謂詞索引列上如此大幅減慢查詢?如果是這樣,爲什麼?

當然可以。

通常,謂詞推送使優化程序選擇NESTED LOOPS而不是HASH JOIN

如果條件沒有選擇性,這可能會變慢。

這個查詢

SELECT * 
FROM table1, t1 
     (
     SELECT /*+ NO_PUSH_PRED */ 
       * 
     FROM table2 t2 
     WHERE t2.col1 = :value1 
     ) t2o 
WHERE t2o.col2 = t1.col2 

將最有可能建設超過table1內容的哈希表,並通過探頭對這個哈希表(反之亦然)的視圖返回的行。

這個查詢:

SELECT * 
FROM table1, t1 
     (
     SELECT /*+ PUSH_PRED */ 
       * 
     FROM table2 t2 
     WHERE t2.col1 = :value1 
     ) t2o 
WHERE t2o.col2 = t1.col2 

將使用NESTED LOOPS(t2.col1, t2.col2)索引,如果它的定義。

如果col2table2有選擇性,則後者更有效,如果不是,則效率更低。

我的教育猜測是,這正是你的情況發生了什麼。

如果您發佈您的查詢和執行計劃,我可能會告訴更多。

+0

感謝您的解釋。如果使用謂詞推送,簡單地改變連接的語法會改變嗎? – jnt30 2009-06-25 18:13:42