42.5. 規劃器/優化器

規劃器/優化器的任務是創建一個優化了執行規劃。 一個特定的 SQL 查詢(因此也就是一個查詢樹)實際上可以以多種不同的方式執行, 每種都生成相同的結果集。如果可能,查詢優化器將檢查每個可能的執行規劃,最終選擇運行最快的執行計劃。

注意: 有些情況下,檢查一個查詢所有可能的執行方式會花去很多時間和內存空間。 特別是在正在執行的查詢涉及大量連接操作的時候。為了在合理的時間裡判斷一個合理的(而不是優化的)查詢計劃。 PostgreSQL 使用 基因查詢優化

在找到最經濟的路徑之後,就制作一個 規劃樹傳遞給執行器。 它有足夠的詳細信息,代表著需要執行的計劃,執行器可以讀懂並運行之。

42.5.1. 生成可能的規劃

規劃器/優化器以查詢裡出現的在關系上定義的索引的類型為基礎, 判斷應該生成哪些規劃。對一個關系總是可以進行一次順序查找, 所以總是會創建只使用順序查找的規劃。 假設一個關系上定義著一個索引(例如 B-tree 索引), 並且一條查詢包含約束 relation.attribute OPR constant。如果 relation.attribute 碰巧匹配 B-tree 索引的關鍵字並且 OPR 又是列出在索引的操作符表中的操作符中的一個, 那麼將會創建另一個使用 B-tree 索引掃描該關系的規劃。 如果還有別的索引, 而且查詢裡面的約束又和那個索引的關鍵字匹配,則還會生成更多的規劃。

在尋找完掃描一個關系的所有可能的規劃後, 接著創建聯接各個關系的規劃。 規劃器/優化器首先考慮在 WHERE 條件裡存在連接子句的連接(比如,存在象 where rel1.attr1=rel2.attr2 這樣的約束)。 沒有連接子句的的連接對只有在沒有別的選擇的時候才考慮,也就是說, 一個關系沒有和任何其它關系的連接子句可用。 規劃器/優化器為它們認為可能的所有的連接關系對生成規劃。 有三種可能的連接策略:

完成的查詢樹由對基礎關系的順序或者索引掃描組成,並根據需要加上嵌套循環, 融合,或者散列連接節點,加上任何需要的輔助步驟,比如排序節點或者聚集函數計算節點等。 大多數這些規劃節點類型都有額外的做選擇(拋棄那些不符合指定布爾條件的行)和投影 (基于給出的字段數值,計算一個派生出的字段集,也就是,在需要時計算標量表達式)。 規劃器的一個責任時從 WHERE 子句中附加選擇條件以及為規劃樹最合適的節點計算所需要的輸出表達式。