全部產品
Search
文件中心

AnalyticDB:常見問題以及改進措施

更新時間:Jul 06, 2024

由於資料分布和查詢複雜度等因素,可能出現查詢效能不符合預期的情況,檢查查詢的執行計畫是重要的問題排查方式之一。

常見計劃問題

  • Join Method以及Inner和Outer表

    根據Join Method選擇Inner和Outer表, 一般情況下AnalyticDB MySQL版自動選擇Join的左右表,您也可以自行檢查左右表的選擇是否合理。

    Hash Join中,右表建立Hash,左表去右表中尋找合格資料,一般右表要盡量小於左表,以減少建立Hash表的開銷以及Hash表的大小。您可以通過檢查Join表過濾後的大小來查看對應的左右表選擇是否合理。但由於還有多表Join的中間結果,以及Join Type等因素影響,Join的左右表的選擇也不能單純依賴表過濾後的大小來選擇。

  • Join Order

    Join Order的最佳化是最佳化器的核心挑戰之一,也是經典的NP-hard問題。AnalyticDB MySQL版最佳化器對於不同的負載提供兩種Join Reordering策略。Left Deep Tree(LDT)一般適用於較簡單查詢情境,Bushy Tree(BT)適用較複雜的負載查詢。Bushy Tree一般會將過濾效果更好的表放在前面,對於複雜查詢能夠產生更優的Join Order。

    對於複雜查詢,人為確認最佳Join Order非常困難。Join表數量較大時,需要資深的專家進行調優。建議將過濾效果更好的表放在Join Sequence之前,可以更早更快的過濾掉不需要的資料。

  • 分布式Aggregation

    AnalyticDB MySQL版提供分布式彙總計算能力,可以根據計算資料量分步做彙總計算。一般情況下,AnalyticDB MySQL版的最佳化器可以選擇最佳彙總計算計劃,但在資料扭曲比較嚴重等情境下,最佳化器對於彙總資料分布估算的誤差會比較大,從而造成彙總計算效能問題。例如,一般AnalyticDB MySQL版會選擇兩階段彙總計算,在各個計算節點本地做一次部分彙總(Partial Aggregation),減少彙總計算資料量,然後再根據彙總列Reshuffle做一次Final Aggregation。一般情況下,部分彙總可以顯著減少彙總計算的資料量,但如果遇到資料扭曲嚴重,或者部分彙總列比較Unique從而不能減少彙總計算數量的情況下,部分彙總反而會帶來額外的效能開銷而非收益。

  • 其它問題

    本文只列舉了幾類常見的查詢計劃問題,例如全表掃描時出現無過濾條件的大表、可以下推的過濾條件沒有下沉到儲存等複雜計劃和效能問題等,需要AnalyticDB MySQL版專家服務小組來協助定位排查。

改進執行計畫

  • 收集統計資訊

    AnalyticDB MySQL版的查詢最佳化工具根據統計資訊估算不同計劃的開銷,並選擇最佳計劃。統計資訊會自動收集,一般不需要使用者關心,詳情請參見自動收集統計資訊。對於建立的表,系統可能還未及時收集統計資訊,您可以通過select * from information_schema.column_statistics; 查看查詢關聯的表是否有統計資訊(3.1.6及之後的版本才有此系統資料表)。如果查詢關聯的表沒有統計資訊,可以先手動執行收集命令收集一次,之後交給自動收集模組去收集即可。手動收集統計資訊的詳情,請參見手動收集統計資訊

  • 調整Join Order

    通常AnalyticDB for MySQL可以選擇最佳的Join Order,由於資料分布特性以及查詢自身的複雜度等因素,在某些情境下可能存在無法選擇最優Join Order,查詢效能較低,您可以通過在Hint中引入reorder_joins參數設定是否手動調整Join Order。

    • /*+reorder_joins=false*/;,開啟手動調整Join Order開關,然後通過修改查詢中各個表出現的順序來控制Join Order。
    • /*+reorder_joins=true*/;,關閉手動調整Join Order開關,系統會自動選擇Join Order,絕大多數情境下可以獲得最佳Join Order。
    例如上述樣本中的nation、region、customer表,AnalyticDB MySQL版給出的Join Order是region > nation > customer。如果根據實際查詢效能得出更好的Join Order:customer > nation > region,可以如下所示在查詢前使用Hint改變查詢中表的順序。
    /*+ reorder_joins=false */
           EXPLAIN SELECT count(*)
           FROM    customer, nation, region
           WHERE c_nationkey = n_nationkey
           AND n_regionkey = r_regionkey
           AND r_name = 'ASIA';                       
           | Plan Summary  |
           +---------------+
           1- Output[ Query plan ]
           2  -> Aggregate (FINAL)
           3    -> LocalExchange[SINGLE]
           4      -> Exchange[GATHER]
           5        -> Aggregate (PARTIAL)
           6          -> InnerJoin[Hash Join]
           7            - Project
           8              -> InnerJoin[Hash Join]
           9                - ScanProject {table: customer}
           10                  -> TableScan {table: customer}
           11                -> LocalExchange[HASH]
           12                  -> Exchange[REPLICATE]
           13                    - ScanProject {table: nation}
           14                      -> TableScan {table: nation}
           15            -> LocalExchange[HASH]
           16              -> Exchange[REPLICATE]
           17                - ScanProject {table: region}
           18                  -> TableScan {table: region}                    

查詢計劃調優是一個非常廣泛的領域,本文簡要討論AnalyticDB MySQL版中的查詢計劃調優基礎方法,後續將不斷更新更多的調優最佳實務。