PostgreSQL的查詢優化
PostgreSQL的查詢優化
資料庫管理系統中的SQL執行,有多種多樣,從SQL語句型別上講,有DDL、DML、DQL、DCL。不同語句,被資料庫引擎執行,其執行方式、複雜程度都不相同。
其中,最為複雜的,是DQL,查詢語句。查詢語句的執行,在資料庫中,又可以分為2個階段,一是查詢計劃的生成(PG的處理方式包括:預處理、生成路徑)、二是依據查詢計劃做查詢動作的執行。
查詢語句,本依據SQL語句的語義,逐一執行使用者指定的動作即可,但是,查詢語句,可以做等價變換,這樣可以使得查詢的實際效率得以提高。於是,有了查詢優化一說。查詢優化,基於關係代數變換,把使用者指定的SQL經過“等價”的代數轉換,變為一種更節省
查詢計劃的生成,是基於關係代數的。用於簡化所有型別表示式中最通用的代數定律是交換律和結合律。交換律和結合律的存在,使得在SELECT查詢語句中的From-list字句中的物件可以被等價變換位置,這樣,有利於2個表在記憶體裡做連線(一些連線演算法是根據表的資料量來決定是表A連線表B還是表B連線表A,這樣的操作,在理論上沒有差別,但在演算法上,會導致IO的不同,因此,好的連線次序,能提高連線效率。而選擇哪種方式,是根據預估數值的最終計算值比較大小選取最小的值的)。對於被選擇的目標物件(
查詢計劃的生成,還和多個關係做連線有關係。如果存在多個關係(表)做連線,則連線的順序,也影響著查詢的效率,所以,查詢優化,也會討論如何決定多個關係之間做連線,優先連線哪些關係。
查詢計劃的生成,是根據關係代數對各種關係的連線可能進行計算(找出多條路徑,計算的數值很重要,通常資料庫引擎有個預估值,還有個不斷收集需要的值的統計者如行數列數等統計者),找出其中總值最小的,作為執行的路徑,送交執行器執行。但多個關係之間的連線代價如何計算,也是一個需要關注的問題。
查詢計劃的執行,在資料庫引擎中是執行器所完成的工作。執行器根據查詢計劃,逐步呼叫相關演算法,執行。這樣的演算法包括:一趟演算法、巢狀迴圈連線、基於排序的兩趟演算法、基於雜湊的兩趟演算法、基於索引的演算法、使用超過兩趟的演算法等等。不同的資料庫,通常會有不同的但類似的實現。
本文的側重點,集中於查詢計劃的生成。查詢計劃的執行,實則是不同演算法的實現,另行講述。
1查詢優化的原理
1.1關係代數
查詢優化,基於“關係代數”。
對於關係代數的初步認識,可以參看:
在資料庫中,表與表之間的連線關係,除了參見上文外,可以參考:
1.2關係代數詳解
參見《資料庫系統實現》。