2011-10-17 73 views
4

我正在運行以下查詢。在oracle中索引是否與組功能一起工作?

SELECT Table_1.Field_1, 
      Table_1.Field_2, 
      SUM(Table_1.Field_5) BALANCE_AMOUNT 
     FROM Table_1, Table_2 
    WHERE Table_1.Field_3 NOT IN (1, 3) 
     AND Table_2.Field_2 <> 2 
     AND Table_2.Field_3 = 'Y' 
     AND Table_1.Field_1 = Table_2.Field_1 
     AND Table_1.Field_4 = '31-oct-2011' 
    GROUP BY Table_1.Field_1, Table_1.Field_2; 

我已經創建了索引列的Table_1(Field_1,Field_2,Field_3,Field_4)但不習慣於索引。

如果我從select子句中刪除SUM(Table_1.Field_5),那麼index正在被使用。

我很困惑,如果優化器沒有使用這個索引或它的因爲SUM()函數我用在查詢中。

請分享你的解釋。

+1

你應該張貼一個優化的執行計劃。 – Benoit

回答

5

當您刪除SUM時,還可以從查詢中刪除field_5。然後可以在索引中找到答覆查詢所需的所有數據,這可能比掃描表更快。如果您將field_5添加到索引,則帶有SUM 的查詢可能使用索引

+0

謝謝託尼!我在索引中添加了field_5,它工作正常。感謝您的寶貴迴應。 –

1

如上所述,求和函數的存在會導致索引被忽略。

function based indexes

基於函數的索引包括要麼通過函數變換列,例如UPPER函數,或者包含在表達,如COL1 COL2 +。

在轉換的列或表達式上定義基於函數的索引允許在WHERE子句或ORDER BY子句中使用該函數或表達式時使用索引返回數據。因此,當頻繁執行的SQL語句在WHERE或ORDER BY子句中包含轉換的列或表達式中的列時,基於函數的索引可能很有用。

然而,與所有的,基於函數索引have their restrictions:

表達的基於函數的索引不能包含任何聚集函數。表達式必須只引用表格中一行中的列。

3

如果您的查詢返回了大部分錶行,Oracle可能會決定執行全表掃描比索引和表堆之間的「跳躍」要便宜(以獲取Table_1.Field_5中的值)。

嘗試將Table_1.Field_5添加到索引(因此覆蓋整個查詢與索引),看看是否有幫助。

請參閱使用索引盧克的Index-Only Scan: Avoiding Table Access以瞭解發生了什麼情況的概念說明。

+0

謝謝Branko!這解決了這個問題。 –

+0

@AnupGadve然後一點點upvote?請?漂亮嗎? ;) –

+0

我試過了,但它需要聲望點.... :) –

0

雖然我看到一些很好的答案在這裏幾個重要的點被錯過 -

SELECT Table_1.Field_1, 
      Table_1.Field_2, 
      SUM(Table_1.Field_5) BALANCE_AMOUNT 
     FROM Table_1, Table_2 
    WHERE Table_1.Field_3 NOT IN (1, 3) 
     AND Table_2.Field_2 <> 2 
     AND Table_2.Field_3 = 'Y' 
     AND Table_1.Field_1 = Table_2.Field_1 
     AND Table_1.Field_4 = '31-oct-2011' 
    GROUP BY Table_1.Field_1, Table_1.Field_2; 

話說有SUM(Table_1.Field_5)在SELECT子句導致指數不會在不正確使用。你的索引(Field_1,Field_2,Field_3,Field_4)仍然可以使用。但是你的索引和sql查詢有問題。

由於您的指數只有上(Field_1,Field_2,Field_3,Field_4)即使你的索引被使用DB將要訪問實際的錶行,爲應用過濾器獲取Field_5。現在它完全依賴於sql優化器繪製的執行計劃,哪一個是成本有效的。如果SQL優化器發現full table scan的成本低於使用索引,它將忽略該索引。這樣說,我現在就告訴你,你的指數可能的問題 -

  1. 正如其他人指出,你可以簡單地添加Field_5到索引,以便有沒有必要單獨的表訪問。
  2. 索引的順序對於性能非常重要。例如。在你的情況下,如果你的訂單是(Field_4,Field_1,Field_2,Field_3),那麼它會更快,因爲你在Field_4上擁有平等 - Table_1.Field_4 = '31-oct-2011'。想想這是 -

Table_1.Field_4 = '31-oct-2011'會給你更少的選擇,從那裏選擇最終結果Table_1.Field_3 NOT IN (1, 3)。因爲你正在做一個連接,所以事情可能會改變最好查看執行計劃並相應地設計您的索引/ sql。

相關問題