關於執行計划Cost的三個疑問:
1. 執行計划的Cost越低,SQL就一定跑得越快嗎?或者說Cost 和 執行時間成比例關系嗎?
2. Oracle 默認產生的執行計划是Cost最低的嗎?
3. 如果對象的統計信息都是最新的,執行計划就一定是准確和最優的嗎?
實踐出真知:
發現一條SQL,跑很久也沒結果出來。
SQL不是很長,但是執行計划很長。
SQL文本:
SELECT TO_CHAR(SYSDATE, 'yyyy-mm-dd') AS STAT_DATE, SYSDATE AS STAT_TIME, X.TABLE_NAME, NVL(X.NUM_ROWS, 0) AS TABLE_ROWS, NVL(ROUND(X.NUM_ROWS * X.AVG_ROW_LEN / 1024, 2), 0) AS TABLE_SIZES, Y.CREATED AS CREATE_TIME, Z.COMMENTS AS TABLE_COMMENT, H .COL_CNT FROM ALL_TABLES X, ALL_OBJECTS Y, ALL_TAB_COMMENTS Z, (SELECT H .TABLE_NAME, COUNT(1) AS COL_CNT FROM ALL_TAB_COLS H WHERE H.OWNER = 'TOSSKA' GROUP BY H .TABLE_NAME) H WHERE X.TABLE_NAME = Y.OBJECT_NAME AND X.TABLE_NAME(+) = Z.TABLE_NAME AND X.TABLE_NAME = H.TABLE_NAME AND Y.OBJECT_TYPE IN ('TABLE PARTITION', 'TABLE') AND X. OWNER = 'TOSSKA' AND Y. OWNER = 'TOSSKA' AND Z. OWNER = 'TOSSKA' ORDER BY X.TABLE_NAME
執行計划:
執行計划有214個步驟。太長了影響閱讀,這里只顯示小部分執行計划,大約十分之一吧。
在 Tosska SQL Tuning Expert for Oracle 中輸入SQL,點擊Tune開始自動優化。
一邊喝咖啡, 一邊等待…
優化結束后,工具幫我找到了5條更快的等價SQL.
有興趣的朋友,可以將SQL中的OWNER從TOSSKA改為自己數據庫上的用戶名(用戶下要有大量的表,否則SQL沒有返回結果集,看不出效果),親自試一試。
讓我們來分析下6條SQL(原SQL,5條優化后更快的SQL) 執行計划Cost和性能之間的關系。
下圖可以看出來,Cost和SQL執行時間並不成比例關系。
仔細觀察原SQL和優化后的SQL,我們來回答博客開頭提出的三個問題。
- SQL 127 和 SQL 129 的Cost比原始SQL高很多,大約是原始SQL的3倍,但是速度卻比原始SQL快很多。換句話說,Cost只是估計值,和真實的速度沒有直接關系。
- 原始SQL的Cost是1330, 等價SQL 130, SQL 135 和 SQL 45的Cost 都比原始SQL低。然而Oracle並沒有選中這些Cost更低的執行計划。 換句話說,Cost低的執行計划漏選了。Oracle並沒有錯,SQL優化器不能遍歷所有執行計划,然后找出Cost最低的執行計划;否則尋找Cost最低的執行計划所耗費的時間,可能會超過SQL執行所需要的時間, 得不償失。
- CBO 是基於對象的統計信息,根據一堆公式估算執行計划成本和返回行數的,難免會出現誤差;當誤差級聯放大之后,就可能導致產生次優或者不好的執行計划;這也是Oracle推出Adaptive Plan的一個原因;
Oracle是目前最強大的數據庫,但是優化潛力依然巨大, 這也是眾多SQL優化專家和優化工具的價值所在。
感受SQL優化工具的魅力,分享SQL優化故事…
SQL 優化工具下載:
https://www.tosska.cn/tosska-sql-tuning-expert-tse-oracle-free-download-zh/