高階資料庫十五:查詢優化器(一)
Optimizer Implementation(Part I)
背景
在講述這個優化器的時候,就必須先了解查詢過程。在本系列的資料庫四:淺談資料庫查詢過程(Query Processing)中大致地說明了一下資料庫的查詢過程,但是沒提到查詢優化器的具體策略與實現。
對於查詢而言,我們期望優化器的作用是找到最小代價的正確執行方案。但是這是一個NP完全問題,所以沒有一個優化器能夠真正地找到真正的最佳方案。
關於OLTP的查詢優化會更加簡單,一般來說選取最好的索引,JOIN操作也大多使用外來鍵,用一些簡單的策略就行。
比如,大家可以畫一棵關係代數查詢樹,如果我們將選擇操作儘可能下放到深處,則在進行笛卡爾乘或者JOIN的時候,參與運算的資料就少了。這就是heuristic optimazation。
所以在這兒我們將說明OLAP查詢的優化策略。
優化器基礎
優化器粒度
單查詢
- 更小的搜尋空間。
- DBMS不能在查詢中重複使用結果。
- 為了解決資源爭奪問題,成本模型必須考慮當前正在執行的內容。
多查詢
- 如果有很多類似的查詢,效率會更高。
- 搜尋空間要大得多。
- 用於掃描共享(之後的文章會提到,大致就是多個查詢共用一個掃描表的結果,而不是各自掃描一次)
優化時間
靜態優化
- 在執行之前選擇最佳計劃。
- 計劃質量取決於成本模型的準確性。
- 可以使用準備好的支票分攤執行。
動態優化
- 主要在流式資料的時候使用
- 查詢執行時,即時選擇運營商計劃。
- 將重新優化多次執行。
- 難以實現/除錯(非確定性)
混合優化
- 使用靜態演算法編譯。
- 如果估計>閾值的誤差,則重新優化。
計劃穩定
提示
- 執行資料庫系統管理員幫助優化器進行決策,比如,我希望用hash表進行JOIN等
- mysql、sqlserver似乎都支援這種方法
固定優化器版本
- 設定優化器版本號並將查詢逐個遷移到新優化器。比如,雖然用了新版本的資料庫,但是對於某種特定的查詢,我們發現了舊版本的優化器似乎更快,則可以將版本調回去。
向後相容的計劃
- 從舊版本儲存備份查詢計劃,並將其提供給新的DBMS。
優化器搜尋策略
Heuristics
之前舉了一個關係代數查詢樹的例子,說的就是Heuristics優化方法。它定義了一些規則,通過靜態的方式來進行優化:
- 儘早進行選擇,越嚴格的限制應該越早進行
- 在連線之前執行所有選擇
- 謂詞/限制/投影下推
- 基於基數加入排序
Oracle在早起非常受歡迎的原因就是因為它使用了這種方法。
優點:
- 易於實施和除錯。
- 效果相當好,對於簡單的查詢很快。
缺點:
- 依靠玄學常數來預測計劃決策的有效性。
- 當操作之間存在複雜的相互依賴關係時,幾乎不可能產生好的查詢計劃。
Heuristics + Cost-based Join Order Search
使用靜態規則執行初始優化,然後使用動態規劃來確定表格的最佳連線順序。
- 第一個基於成本的查詢優化器
- 使用分而治之搜尋方法進行自底向上(向前連結)
現在也非常常用的技術,MySQL、SQLite都用這個。
SYSTEM R OPTIMIZER
假設都沒有索引,則得到資料的方式就是線性掃描。
然後將所有的JOIN操作的可能性都列出來,並找出最少代價的JOIN策略。其中也包括每個具體的JOI操作的演算法。
因為有ORDER BY,所以要進行排序
優點:
- 通常找到一個合理的計劃,而不必執行詳盡的搜尋。
缺點:
- 所有與啟發式方法相同的問題。
- 左深連線樹並不總是最佳的。
- 必須考慮成本模型中資料的物理屬性(例如排序順序)。
Randomized Algorithms
執行隨機遍歷查詢的所有可能(有效)計劃的解決方案空間。
繼續搜尋,直到達到代價閾值或優化器執行一段特定的時間。
例如:Postgres的遺傳演算法。
優點:
- 隨機跳轉搜尋空間允許優化器跳出區域性最小值(這個地方可以去看看遺傳演算法的文章來理解原理)。
- 低記憶體開銷(如果沒有歷史儲存)。
缺點:
- 很難確定為什麼DBMS可能選擇了一個特定的計劃。
- 必須做額外的工作來確保查詢計劃是確定性的。
- 仍然必須執行正確性規則。
SIMULATED ANNEALING
用Heuristics方發生成的最初的查詢計劃,然後通過SQL運算子的隨機排列(例如,交換兩個表的連線順序)來產生新的解。
- 始終接受降低成本的更改
- 只接受一個可能會增加成本的變化。
- 拒絕違反正確性的任何更改(例如,排序順序)
POSTGRES OPTIMIZER
更復雜的查詢使用遺傳演算法來選擇連線順序的。
在每一輪開始時,生成查詢計劃的不同版本,選擇成本最低的計劃,並用其他計劃進行排列。重複該操作。
- 變異函式只產生有效的計劃。
Stratified Search
首先使用轉換規則重寫邏輯查詢計劃。
- 引擎檢查是否允許轉換,然後才能應用。
- 這一步從來不考慮成本。
然後執行基於成本的搜尋,從而將邏輯查詢計劃對映到物理查詢計劃。
優點:
- 在快速表現的實踐中運作良好。
缺點:
- 難以為轉換指定優先順序
- 如果不計算多重成本估算,一些轉換難以評估。
- 規則維護是一個巨大的痛苦。
STARBURST OPTIMIZER
用此方法實現更好地System R optimizer。
階段1:查詢重寫
- 計算查詢的SQL塊級關係微積分表示。
階段2:計劃優化
- 一旦查詢重寫完成,執行System RR風格的動態規劃階段。
Unified Search
使用唯一的一個搜尋空間,統一邏輯- 邏輯和邏輯- 物理轉換的概念。 不需要單獨的階段,因為一切都是轉換。
這種方法產生了更多的轉換,因此大量使用memoization來減少冗餘工作。
VOLCANO OPTIMIZER
通用基於成本的查詢優化器,基於關係代數上的等價規則。
- 輕鬆新增新的操作和等價規則。
- 計劃過程中將資料的物理屬性視為一流的實體。
- 使用分枝定界搜尋的自頂向下方法(反向連結)。
不過這種方法似乎只在實驗室或者學校中才有用到,工業界似乎沒有用過這種方式。
優點
- 使用宣告性規則來生成轉換。
- 通過高效的搜尋引擎實現更好的可擴充套件性。 減少使用記憶的冗餘估計。
缺點:
- 在優化搜尋之前,所有等價類都完全展開以生成所有可能的邏輯運算子。
- 不容易修改謂詞。
TOP-DOWN VS. BOTTOM-UP
自上而下的優化:從你想要的最終結果開始,然後在樹上尋找最適合你的目標。
自下而上的優化:從一無所有開始,然後制定計劃以達到您想要的最終結果。