postgresql
的查詢優化
資料庫管理系統中的
sql執行,有多種多樣,從
sql語句型別上講,有
ddl、
dml、
dql、
dcl。不同語句,被資料庫引擎執行,其執行方式、複雜程度都不相同。
其中,最為複雜的,是
dql,查詢語句。查詢語句的執行,在資料庫中,又可以分為
2個階段,一是查詢計畫的生成(
pg的處理方式包括:預處理、生成路徑)、二是依據查詢計畫做查詢動作的執行。
查詢語句,本依據
sql語句的語義,逐一執行使用者指定的動作即可,但是,查詢語句,可以做等價變換,這樣可以使得查詢的實際效率得以提高。於是,有了查詢優化一說。查詢優化,基於關係代數變換,把使用者指定的
sql經過「等價」的代數轉換,變為一種更節省
io(或更節省
cpu,但是,多數資料庫系統的瓶頸在於
io)的執行序列,但使用者的語義沒有發生變化,這樣,執行起來則更為高效。
查詢計畫的生成,是基於關係代數的。用於簡化所有型別表示式中最通用的代數定律是交換律和結合律。交換律和結合律的存在,使得在
select
查詢語句中的
from-list
字句中的物件可以被等價變換位置,這樣,有利於
2個表在記憶體裡做連線(一些連線演算法是根據表的資料量來決定是表
a連線表
b還是表
b連線表
a,這樣的操作,在理論上沒有差別,但在演算法上,會導致
io的不同,因此,好的連線次序,能提高連線效率。而選擇哪種方式,是根據預估數值的最終計算值比較大小選取最小的值的)。對於被選擇的目標物件(
select-list
),有些和
where-list
字句或其他字句提及的列物件相關,所以,關係代數中做選擇(投影操作)也存在優化的可能,把一些列「下推」(
pull down
)到其他位置,也可以減少
io,從而提高連線效率。對於一些子查詢等語句(還包括有in、
exist
等涉及半連線、反半連線操作),可以把一些子句「上拉」(
pull up
)到更高層次執行,以節約
io。還有一些操作,如消重、分組等,都有可以優化之處,這全依賴於關係代數規則。在關係代數規則下實現的優化,可以有效去除掉大量
io操作,去掉大量
io,又依賴於對具體演算法的選擇,因此,查詢優化,實則也依賴於查詢執行過程中的具體演算法的「
io預期」。
查詢計畫的生成,還和多個關係做連線有關係。如果存在多個關係(表)做連線,則連線的順序,也影響著查詢的效率,所以,查詢優化,也會討論如何決定多個關係之間做連線,優先連線哪些關係。
查詢計畫的生成,是根據關係代數對各種關係的連線可能進行計算(找出多條路徑,計算的數值很重要,通常資料庫引擎有個預估值,還有個不斷收集需要的值的統計者如行數列數等統計者),找出其中總值最小的,作為執行的路徑,送交執行器執行。但多個關係之間的連線代價如何計算,也是乙個需要關注的問題。
查詢計畫的執行,在資料庫引擎中是執行器所完成的工作。執行器根據查詢計畫,逐步呼叫相關演算法,執行。這樣的演算法包括:一趟演算法、巢狀迴圈連線、基於排序的兩趟演算法、基於雜湊的兩趟演算法、基於索引的演算法、使用超過兩趟的演算法等等。不同的資料庫,通常會有不同的但類似的實現。
本文的側重點,集中於查詢計畫的生成。查詢計畫的執行,實則是不同演算法的實現,另行講述。
查詢優化,基於「關係代數」。
對於關係代數的初步認識,可以參看:
在資料庫中,表與表之間的連線關係,除了參見上文外,可以參考:
資料庫查詢中的表連線(一):
資料庫查詢中的表連線(二):
參見《資料庫系統實現》。
PostgreSQL 查詢優化與維護命令
不同rdbms中提供的不同型別統計功能,查詢優化器和查詢計畫器依賴統計資訊選擇並生成最佳查詢執行計畫,因此它非常重要。postgresql 資料庫也管理不同型別的統計,查詢優化器依賴它們生成最佳查詢執行計畫。假設有一張表有100000行記錄,但表統計資料沒有更新,僅顯示1000個元組資訊。查詢優化器...
PostgreSQL查詢優化器原始碼分析 整體流程
函式間關係的主要邏輯如下 planner 第 11 層結束,build join rel 第 10 層結束,make join rel make rels by clause joins 會呼叫make join re l make rels by clauseless joins 會呼叫make ...
記一次postgresql查詢優化
一 場景介紹 1 需求 根據schema 1中多表聯查結果,對相應schema 2中資料進行刪除操作。2 表結構 模式表名 表結構schema 1 table 1 id varchar 32 pk主鍵 table 2 id varchar 32 pk主鍵 table 1 id varchar 32 ...