最近看了一個關于oracle SQL性能調優的在線課程。在視頻中,講師在比較兩個查詢的性能時不斷比較 Autotrace 中的 COST 值。
但我也從其他論壇和網站上讀到過,其中指出 COST 是特定于該查詢的相對值,不應用作評估性能的絕對指標。他們建議改為查看一致獲取、物理讀取等內容。
所以我的解釋是,比較用于不同目的的完全不同查詢的 COST 值是沒有意義的,因為 COST 值是相對的。但是,當比較相同的 2 個查詢時,其中一個已針對“更好的性能”進行了輕微修改,可以比較 COST 值。我的解釋準確嗎?
什么時候可以比較 COST 值而不是其他一些指標?
在評估/比較查詢性能時,我們還應該查看哪些其他指標?
uj5u.com熱心網友回復:
一般來說,我會非常謹慎地比較cost兩個查詢之間的比較,除非您有非常具體的理由相信這是有道理的。
通常,人們不會查看優化器為其生成(幾乎)最佳計劃的 99.9% 的查詢。人們會查看優化器產生明顯次優計劃的查詢。優化器將出于兩個基本原因之一生成次優計劃 - 它無法將查詢轉換為可以優化的形式(在這種情況下,人類可能需要重寫查詢)或它正在使用的統計資訊做出它的估計是不正確的,所以它認為的最佳計劃不是。(當然,查詢可能會變慢還有其他原因——也許優化器生成了一個最佳計劃,但該最佳計劃正在執行表掃描,因為例如缺少索引。)
如果我正在查看一個速度很慢的查詢,并且該查詢似乎寫得相當好,并且有一組合理的索引可用,那么統計資料很可能是問題的根源。然而,由于cost完全基于統計資料,這意味著優化器的cost估計是不正確的。如果它們不正確,cost則大致相同的可能性是錯誤地高或錯誤地低。如果我查看我知道需要聚合數十萬行以生成報告的查詢的查詢計劃,并且我看到優化器已為其分配了一位數cost,我知道它正在估計沿線某處一個步驟將回傳太少的行。為了調整該查詢,我需要cost上升,以便優化器的估計準確反映現實。如果我查看一個查詢的查詢計劃,我知道應該只需要掃描少數幾行并且我看到cost數以萬計的行,我知道優化器正在估計某個步驟將回傳太多行。為了調整該查詢,我將需要cost關閉,以便優化器的估計反映現實。
如果您使用gather_plan_statistics提示,您將在查詢計劃中看到估計的和實際的行數。如果優化器的估計接近現實,那么該計劃可能非常好并且cost可能相當準確。如果優化器的估計不正確,則計劃可能很差,并且cost很可能是錯誤的。嘗試使用cost度量來調整查詢而不首先確認它cost合理地接近現實很少是非常有成效的。
就個人而言,我會忽略cost并專注于隨著時間的推移可能穩定并且實際上與性能相關的指標。我的偏向是專注于邏輯讀取,因為大多數系統都受 I/O 限制,但您也可以使用 CPU 時間或運行時間(不過,運行時間往往不是特別穩定,因為它取決于快取中發生的情況在運行查詢時)。如果您正在查看計劃,請關注估計的與實際的行數,而不是cost.
uj5u.com熱心網友回復:
查詢的實際運行時間是迄今為止調優查詢的最重要指標。我們可以在 99.9% 的情況下忽略成本和其他指標。
如果查詢相對較小且速度較快,我們可以輕松地重新運行它并通過GATHER_PLAN_STATISTICS提示找到實際運行時間:
-- Add a hint to the query and re-run it.
select /* gather_plan_statistics */ count(*) from all_objects;
-- Find the SQL_ID of your query.
select sql_id, sql_fulltext from gv$sql where lower(sql_text) like '%gather_plan_statistics%';
-- Plus in the SQL_ID to find an execution plan with actual numbers.
select * from table(dbms_xplan.display_cursor(sql_id => 'bbqup7krbyf61', format => 'ALLSTATS LAST'));
如果查詢很慢,并且我們不能輕易地重新運行它,則生成 SQL Monitor 報告。此資料通常在最后一次執行后的幾個小時內可用。
-- Generate a SQL Monitor report.
select dbms_sqltune.report_sql_monitor(sql_id => 'bbqup7krbyf61') from dual;
有整本書都是關于解釋結果的。基礎是您要首先檢查執行計劃并關注具有最大“A-Time”的操作。如果您想了解查詢或優化器出錯的地方,請將“E-Rows”與“A-Rows”進行比較,因為估計的基數會驅動大??多數優化器決策。
示例輸出:
SQL_ID bbqup7krbyf61, child number 0
-------------------------------------
select /* gather_plan_statistics */ count(*) from all_objects
Plan hash value: 3058112905
--------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:03.58 | 121K| 622 | | | |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:03.58 | 121K| 622 | | | |
|* 2 | FILTER | | 1 | | 79451 |00:00:02.10 | 121K| 622 | | | |
|* 3 | HASH JOIN | | 1 | 85666 | 85668 |00:00:00.12 | 1479 | 2 | 2402K| 2402K| 1639K (0)|
| 4 | INDEX FULL SCAN | I_USER2 | 1 | 148 | 148 |00:00:00.01 | 1 | 0 | | | |
...
uj5u.com熱心網友回復:
與工程中的大多數事情一樣,這實際上歸結為您要比較和評估的原因/內容。
COST 是 Oracle 基于時間的一般估計,在其內部優化器中用作排名指標。這個答案很好地解釋了選擇程序。
一般來說,COST 作為衡量標準是比較兩個不同查詢的預期計算時間的好方法,因為它衡量了查詢的估計時間成本,表示為 # of block reads。因此,如果您要比較同一查詢的性能,一個針對時間優化的查詢,那么 COST 是一個很好的指標。
但是,如果您的查詢或系統存在瓶頸或受時間以外的其他因素(例如記憶體效率)的限制,那么 COST 將是一個不好的優化指標。在這些情況下,您應該選擇與您的最終目標相關的指標。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/478843.html
