Explain

EXPLAIN 命令用于顯示 PostgreSQL 執(zhí)行查詢的計劃。它提供了查詢的執(zhí)行步驟、每個步驟的執(zhí)行順序以及預(yù)計的資源消耗。這有助于識別和優(yōu)化性能瓶頸。EXPLAIN 可以與 ANALYZE 結(jié)合使用,以顯示實際執(zhí)行時的詳細統(tǒng)計信息。

EXPLAIN [ANALYZE] [VERBOSE] query;
  • ANALYZE實際執(zhí)行查詢并顯示實際的運行時間和行數(shù)。
  • VERBOSE:顯示更詳細的信息。
EXPLAIN SELECT * FROM orders WHERE customer_id = 123 AND order_date > '2023-01-01';
Seq Scan on orders  (cost=0.00..431.00 rows=21 width=58)
  Filter: ((customer_id = 123) AND (order_date > '2023-01-01'::date))
EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 123 AND order_date > '2023-01-01';
Seq Scan on orders  (cost=0.00..431.00 rows=21 width=58) (actual time=0.016..0.021 rows=1 loops=1)
  Filter: ((customer_id = 123) AND (order_date > '2023-01-01'::date))
  Rows Removed by Filter: 5
Planning Time: 0.150 ms
Execution Time: 0.035 ms
輸出說明
EXPLAIN SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2;

                                        QUERY PLAN
------------------------------------------------------------------------------------------
 Hash Join  (cost=230.47..713.98 rows=101 width=488)
   Hash Cond: (t2.unique2 = t1.unique2)
   ->  Seq Scan on tenk2 t2  (cost=0.00..445.00 rows=10000 width=244)
   ->  Hash  (cost=229.20..229.20 rows=101 width=244)
         ->  Bitmap Heap Scan on tenk1 t1  (cost=5.07..229.20 rows=101 width=244)
               Recheck Cond: (unique1 < 100)
               ->  Bitmap Index Scan on tenk1_unique1  (cost=0.00..5.04 rows=101 width=0)
                     Index Cond: (unique1 < 100)

https://www.postgresql.org/docs/current/using-explain.html
輸出一個查詢計劃的樹結(jié)構(gòu),最底層的是掃面結(jié)點,子節(jié)點先執(zhí)行,然后執(zhí)行上層節(jié)點,最上層的節(jié)點是語句的總體解釋。每個節(jié)點使用 -> 表示其層級關(guān)系和執(zhí)行順序

  1. Seq Scan on orders:表示對 orders 表進行順序掃描。
  2. cost=0.00..431.00:表示預(yù)計的啟動成本(0.00)和總成本(431.00)。
    • 啟動成本:從開始執(zhí)行到輸出第一行的成本。(比如排序,或者過濾的消耗)
    • 總成本:處理完所有行的總成本。
  3. rows=21:估計的返回行數(shù)。
    返回的行數(shù)是預(yù)估的,所以不一定準確, 數(shù)據(jù)庫會對數(shù)據(jù)進行采樣預(yù)估
  4. width=58:每行的字節(jié)數(shù)。
  5. Filter:應(yīng)用的過濾條件。
  6. actual time=0.016..0.021:實際開始時間(0.016 ms)和結(jié)束時間(0.021 ms)。
  7. rows=1:實際返回的行數(shù)。
  8. loops=1:執(zhí)行的循環(huán)次數(shù)。
  9. Rows Removed by Filter: 5:被過濾條件排除的行數(shù)。
  10. Planning Time:查詢計劃生成所需時間。
  11. Execution Time:實際查詢執(zhí)行所需時間。

常見的節(jié)點操作類型

掃描

Seq Scan:逐行掃描整個表,檢查每一行是否符合查詢條件。

適用于小表或無索引的查詢。
全表掃描,可能會較慢,對于大表特別不高效。

Index Scan:使用索引掃描,適用于有索引的列。

適用于有索引的表。
更快的查詢速度,因為只掃描符合條件的部分數(shù)據(jù)。
會連接原來的表數(shù)據(jù)
對于范圍查詢,Index Scan會先查找范圍的起始值,然后順序讀取所有符合條件的條目。

Index Only Scan:僅使用索引數(shù)據(jù),無需訪問表數(shù)據(jù)。
Bitmap Heap Scan:結(jié)合位圖索引掃描和堆掃描。

Bitmap Index Scan:首先,數(shù)據(jù)庫系統(tǒng)使用位圖索引掃描(Bitmap Index Scan)來查找符合查詢條件的行的位圖。這些位圖是索引的“位圖表示”,標識了哪些索引項匹配查詢條件。
Bitmap Heap Scan:然后,數(shù)據(jù)庫系統(tǒng)使用生成的位圖來訪問堆表(即實際數(shù)據(jù)表),從中提取符合條件的行。
適用范圍:
范圍掃描:當查詢條件匹配的數(shù)據(jù)范圍較大,Bitmap Heap Scan 可以更高效地處理這種情況。(比起index scan 不用遍歷過去)
多條件查詢:當查詢涉及多個條件時,位圖索引掃描可以有效地結(jié)合多個索引的結(jié)果

連接

  • Join Type
    內(nèi)連接,左連接,右連接,全連接
  • Inner Unique
    內(nèi)表的連接鍵是否有唯一約束
Nested Loop Join:嵌套循環(huán)連接,用于小數(shù)據(jù)集。

對外部表的每一行執(zhí)行內(nèi)表的掃描,尋找匹配的行。

Hash Join:使用哈希表來執(zhí)行連接操作。

首先對一個表進行哈希,然后使用這個哈希表來查找另一個表中匹配的行。
適用于連接大表,特別是當連接鍵的選擇性較低時。

Merge Join:先對兩個表按連接鍵排序,然后合并匹配的行。

適用于已排序的表或可以快速排序的表。
對于連接鍵的選擇性較高時性能較好。

其他

Hash:計算哈希值
Aggregate 執(zhí)行聚合操作,例如 SUM(), COUNT(), AVG() 等。
Sort 對數(shù)據(jù)進行排序操作
Group 用于對數(shù)據(jù)進行分組,通常與聚合操作一起使用。
Limit 限制查詢結(jié)果的返回行數(shù)
Materialize 用于臨時存儲中間結(jié)果集,以便在查詢執(zhí)行過程中重復使用這些結(jié)果 ,比如CTE
  • Parallel Aware :能否并行
  • Parent Relationship: 和父節(jié)點的關(guān)系
    • Outer:表示這個節(jié)點是作為其父節(jié)點的外部部分執(zhí)行的。例如,在連接操作中,這個節(jié)點可能是外部表的掃描操作。
    • Inner:表示這個節(jié)點是作為其父節(jié)點的內(nèi)部部分執(zhí)行的。例如,在連接操作中,這個節(jié)點可能是內(nèi)表的掃描操作。
    • Top:表示這是查詢計劃的頂層操作,通常是最終的結(jié)果集。

注意如果添加了 ANALYZE, 后面的語句會實際執(zhí)行,所以如果想要不影響數(shù)據(jù)庫的現(xiàn)有數(shù)據(jù),需要執(zhí)行

BEGIN;
EXPLAIN ANALYZE ...;
ROLLBACK;

所以實際使用的時候,并不時一定會使用索引的,比如如果只是過濾一下主鍵,過濾出來的數(shù)據(jù)集還是很大,那么可能用順序掃描,如果指定主鍵是誰,那么會用index掃描

pgadmin里面可以直接用Explain按鈕,帶有圖形化界面,很方便
_serial :執(zhí)行順序,越大的越先執(zhí)行

statistics :有哪些節(jié)點類型,執(zhí)行了多少次,參與了哪些表,表里面什么掃描,掃描了多少次

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容