2008-10-24 57 views
17

我的任務是在工作中優化一些sql查詢。我發現的一切都指向使用解釋計劃來識別問題領域。這個問題我找不出解釋計劃告訴我的究竟是什麼。你得到成本,基數和字節。如何使用Explain Plan來優化查詢?

這是什麼表示,我應該如何使用它作爲指導。低數字更好嗎?高好?任何投入將不勝感激。

或者如果您有更好的方法來優化查詢,我會感興趣。

回答

8

你得到的不僅僅是實際情況,取決於你在做什麼。看看這個explain plan頁面。我假設你在使用Oracle,知道如何運行腳本來顯示計劃輸出。開始時可能更重要的是查看左側是否使用特定索引以及索引是如何使用的。如果您正在進行連接,您應該看到諸如「(Full)」,「(By Index Rowid)」等內容。成本將是下一個要考慮的更低的成本更好,你會注意到,如果你正在做一個沒有使用索引的聯合,你可能會得到一個非常大的成本。您可能還想閱讀有關explain plan columns的詳細信息。

+0

我感謝你的幫助,尤其是鏈接。它現在開始對我產生了影響。再次感謝您的幫助。 – 2008-10-24 18:19:18

+1

加入不使用索引可能不好,他們可能是絕對最好的。這完全取決於。不要,不要試圖消除每個帶索引的全表掃描。 – 2008-10-24 20:11:59

6

你得到了棒棒糖的模糊結束。

絕對沒有辦法,孤立地,沒有大量的額外信息和經驗,查看解釋計劃,並確定什麼(如果有的話)導致低於最佳性能。如果查詢優化可以減少到10個步驟,則可以通過自動化流程完成。我將列出所有你需要了解的有效的事情,但這將是一個很長的名單。

我能想到的唯一簡短的答案是尋找計劃中正在經歷的方式,比您想像的更多的字節。然後考慮如何通過索引或分區來減少這個數量。

嚴重的是,獲得成本喬納森·劉易斯的書基於Oracle Fundementals

找湯姆凱特對Oracle數據庫體系結構的書,租住在樹林小屋幾個星期。

+0

我開始感覺到這並不像我最初在工作中描述的那樣簡單。感謝這本書的建議,它們將被添加到我的書籍列表中以供閱讀。 – 2008-10-26 20:17:39

+1

不要只是將它們添加到隊列中......將它們移動到頂部並盡一切可能來讀取它們。我會先說劉易斯的書。這完全取決於解釋計劃的含義 - 雖然它不是這樣寫的。 – 2008-10-27 14:54:38

4

這是一個龐大的專業領域(又名黑色藝術)。

我一般採取的方法是:

  1. 運行有問題的SQL語句,
  2. 得到實際的計劃(查找DBMS_XPLAN)
  3. 比較估計行數(基數)VS的實際行數。一個很大的差異表明需要修正的問題(例如索引,直方圖)
  4. 請考慮是否可以創建索引以加快部分流程(通常在您概念上認爲該計劃應首先執行的位置)。嘗試一些索引。

您需要了解不同索引在您要求數據庫的環境中的O()影響。它可以幫助您理解數據結構,如B樹,哈希表等。然後,創建一個可能工作並重復該過程的索引。

如果Oracle決定不使用您的索引,請應用INDEX()提示並查看新計劃。成本將大於它選擇的計劃 - 這就是爲什麼它沒有選擇你的指數。暗示的計劃可能會讓你對索引爲什麼不好的原因有所瞭解。

7

我還假設你使用的是Oracle。對於初學者,我還建議您查看解釋計劃網頁。有很多優化,但它可以學習。

一些提示如下:

首先,當你優化別人的任務,他們幾乎一直在尋找可以接受的性能,而不是最終的性能。如果您可以將查詢的運行時間從3分鐘減少到3秒,那麼不要將其減少到2秒,直到您被要求爲止。

其次,請做一個快速檢查以確保您正在優化的查詢在邏輯上是正確的。這聽起來很荒謬,但我無法告訴你我在緩慢運行的查詢中被要求提供建議的次數,只是發現它偶爾會給出錯誤的答案!事實證明,調試查詢通常也加快了速度。

特別是,在解釋計劃中尋找短語「笛卡爾聯接」。如果你看到它,那麼你發現無意識的笛卡爾連接的機會非常好。無意識的笛卡爾連接的通常模式是FROM子句列出以逗號分隔的表,並且連接條件位於WHERE子句中。除了缺少一個連接條件之外,Oracle不得不執行笛卡爾連接。用大桌子,這是一場表演災難。

在查詢邏輯正確的解釋計劃中可以看到笛卡爾連接,但我將其與舊版本的Oracle相關聯。

還查找未使用的複合索引。如果查詢中未使用複合索引的第一列,則Oracle可能無效地使用該索引,或根本不使用該索引。讓我舉一個例子:

的查詢是:

select * from customers  
where 
    State = @State 
    and ZipCode = @ZipCode 

(數據庫管理系統是不是甲骨文,所以,語法是不同的,我已經忘記了當初的語法)。

快速瀏覽索引時,按照順序顯示了客戶索引,其中列 (Country,State,ZipCode)。我改變了查詢閱讀

select * from customers 
    where Country = @Country 
     and State = @State 
     and ZipCode = @ZipCode 

,現在它在大約6秒而不是約6分鐘跑,因爲優化器能夠使用索引來很好的優勢。我問應用程序員爲什麼他們從標準中省略了國家,這是他們的答案:他們知道所有地址的國家都等於'USA',因此他們認爲他們可以通過將該標準放棄而加快查詢速度!

不幸的是,優化數據庫檢索並不像計算時間縮短微秒。它涉及瞭解數據庫設計,尤其是索引,並至少概述了優化器如何執行其工作。

當你學會與它合作而不是試圖超越它時,你通常會從優化器中獲得更好的結果。

祝你好運來加快優化!