1. 程式人生 > >PostgreSQL的查詢優化

PostgreSQL的查詢優化

PostgreSQL的查詢優化

資料庫管理系統中的SQL執行,有多種多樣,從SQL語句型別上講,有DDLDMLDQLDCL。不同語句,被資料庫引擎執行,其執行方式、複雜程度都不相同。

其中,最為複雜的,是DQL,查詢語句。查詢語句的執行,在資料庫中,又可以分為2個階段,一是查詢計劃的生成(PG的處理方式包括:預處理、生成路徑)、二是依據查詢計劃做查詢動作的執行。

查詢語句,本依據SQL語句的語義,逐一執行使用者指定的動作即可,但是,查詢語句,可以做等價變換,這樣可以使得查詢的實際效率得以提高。於是,有了查詢優化一說。查詢優化,基於關係代數變換,把使用者指定的SQL經過“等價”的代數轉換,變為一種更節省

IO(或更節省CPU,但是,多數資料庫系統的瓶頸在於IO)的執行序列,但使用者的語義沒有發生變化,這樣,執行起來則更為高效。

查詢計劃的生成,是基於關係代數的。用於簡化所有型別表示式中最通用的代數定律是交換律和結合律。交換律和結合律的存在,使得在SELECT查詢語句中的From-list字句中的物件可以被等價變換位置,這樣,有利於2個表在記憶體裡做連線(一些連線演算法是根據表的資料量來決定是表A連線表B還是表B連線表A,這樣的操作,在理論上沒有差別,但在演算法上,會導致IO的不同,因此,好的連線次序,能提高連線效率。而選擇哪種方式,是根據預估數值的最終計算值比較大小選取最小的值的)。對於被選擇的目標物件(

select-list),有些和WHERE-list字句或其他字句提及的列物件相關,所以,關係代數中做選擇(投影操作)也存在優化的可能,把一些列“下推”(pull down)到其他位置,也可以減少IO,從而提高連線效率。對於一些子查詢等語句(還包括有INEXIST等涉及半連線、反半連線操作),可以把一些子句“上拉”(pull up)到更高層次執行,以節約IO。還有一些操作,如消重、分組等,都有可以優化之處,這全依賴於關係代數規則。在關係代數規則下實現的優化,可以有效去除掉大量IO操作,去掉大量IO,又依賴於對具體演算法的選擇,因此,查詢優化,實則也依賴於查詢執行過程中的具體演算法的“IO預期”。

查詢計劃的生成,還和多個關係做連線有關係。如果存在多個關係(表)做連線,則連線的順序,也影響著查詢的效率,所以,查詢優化,也會討論如何決定多個關係之間做連線,優先連線哪些關係。

查詢計劃的生成,是根據關係代數對各種關係的連線可能進行計算(找出多條路徑,計算的數值很重要,通常資料庫引擎有個預估值,還有個不斷收集需要的值的統計者如行數列數等統計者),找出其中總值最小的,作為執行的路徑,送交執行器執行。但多個關係之間的連線代價如何計算,也是一個需要關注的問題。

查詢計劃的執行,在資料庫引擎中是執行器所完成的工作。執行器根據查詢計劃,逐步呼叫相關演算法,執行。這樣的演算法包括:一趟演算法、巢狀迴圈連線、基於排序的兩趟演算法、基於雜湊的兩趟演算法、基於索引的演算法、使用超過兩趟的演算法等等。不同的資料庫,通常會有不同的但類似的實現。

本文的側重點,集中於查詢計劃的生成。查詢計劃的執行,實則是不同演算法的實現,另行講述。

1查詢優化的原理

1.1關係代數

查詢優化,基於“關係代數”。

對於關係代數的初步認識,可以參看:

在資料庫中,表與表之間的連線關係,除了參見上文外,可以參考:

1.2關係代數詳解

參見《資料庫系統實現》。