1. 程式人生 > >PostgreSQL學習第十三篇 執行計劃

PostgreSQL學習第十三篇 執行計劃

PostgreSQL中explain的語法:
explain [option] statement
explain [analyze] [verboase] statement

命令的可選選項option為:
analyze
verbose
costs
buffers
format(text|xml|json|yaml)
analyze選項通過實際執行的sql來獲得相應的執行計劃。(實際執行)
verbose用於顯示計劃的附加資訊:計劃樹中每個節點輸出的各個列,如果觸發器被觸發,還有觸發器名稱。預設為false
costs選項顯示每個計劃節點的啟動成本和總成本,以及估計行數和每行寬度。預設為TRUE
buffers:顯示關於緩衝區的使用資訊。該引數只能與analyze引數一起使用。顯示的緩衝區資訊包括共享塊、本地塊和臨時塊讀寫的快熟。預設為false
format指定輸出格式。預設為TEXT


explain輸出結果解釋
簡單示例:
postgres=# explain select * from dog;
                       QUERY PLAN                       
--------------------------------------------------------
 Seq Scan on dog  (cost=0.00..20.80 rows=1080 width=47)
(1 row)

 Seq Scan on dog:全表掃描
cost=0.00..20.80:啟動成本:0.00      返回所有資料的成本:20.80
rows=1080:會返回1080行
width=47:每行平均寬度是47位元組

預設情況下不同操作的cost值:

	1. 順序掃描一個數據庫,cost值為1
	2. 隨機掃描一個數據塊,cost值為4
	3. 處理一個數據行的CPU,cost為0.01
	4. 處理一個索引行的CPU,cost為0.005
	5. 每個操作符的CPU代價為0.0025


以不同格輸出:
explain (format json|xml|yaml) select ....

加analyze引數後,可通過實際執行來獲得更精確的執行計劃。
explain analyze select * ....
explain (analyze true) select * ...

如果只檢視執行的路徑,不看cost值:
select (costs false) select * ...

聯合使用analyze選項和buffers選項,可通過實際執行來檢視實際的代價和緩衝區命中情況:
explain (analyze true,buffers true) select * from ....
postgres=# explain (analyze true,buffers true) select * from dog;
                                            QUERY PLAN                                           
--------------------------------------------------------------------------------------------------
 Seq Scan on dog  (cost=0.00..20.80 rows=1080 width=47) (actual time=0.006..0.006 rows=1 loops=1)
   Buffers: shared hit=1
 Planning time: 0.027 ms
 Execution time: 0.019 ms
(4 rows)

可以檢視插入,刪除等的計劃,但是如果加了analyze,就會真的執行,請注意!

全表掃描:Seq Scan
索引掃描:Index Scan
點陣圖掃描:也是走索引的一種方式。方法是掃描索引,把滿足條件的行或塊在記憶體中建一個位圖,掃描完索引後,再根據點陣圖到表的資料檔案中把相應的資料讀出來。如果走了兩個索引,可以把兩個索引形成的點陣圖進行and或or計算,合併成一個位圖,再到表的資料檔案中把資料讀出來。
當執行計劃的結果行數很多時會進行這種掃描,如非等值查詢、IN子句或有多個條件都可以走不同的索引時。

條件過濾:Filter
巢狀迴圈連線:Nestloop Join,是在兩個表做連線時最樸素的一種連線方式。在巢狀迴圈中,內表被外表驅動,外表返回的每一行都要在內表中檢索找到與它匹配的行,要把返回子集較小的表作為外表。而且在內表的連線欄位上要有索引,否則會很慢。外表為驅動表。

Hash Join:雜湊連線,優化器使用兩個表中較小的表,並利用連線鍵在記憶體中建立散列表,然後掃描較大的表並探測散列表,找出與散列表匹配的行。

Merge Join:合併連線