HighGo Database中auto_explain模組的使用介紹
目錄
文件用途
當我們想要跟蹤大型應用中未優化的查詢時,可使用auto_explain模組提供的一種自動的記錄慢速語句執行計劃的方法。這種方法可以讓我們不必手動的執行EXPLAIN語句,所以使用這種方式是很有幫助的。
詳細資訊
1、使用方法
要想使用這個模組,只需要把它載入到伺服器中(只有資料庫超級使用者可以執行這條指令):
highgo=# LOAD 'auto_explain'; LOAD |
然後無論何時發生了意料之外的慢查詢,我們都可以進行追蹤。
2、配置引數介紹及示例
配置引數控制著auto_explain的行為。需要注意的是,預設情況下的行為是什麼也不做,所以如果想要得到相關結果,必須至少要設定auto_explain.log_min_duration這個引數。注意,只有資料庫超級使用者才能設定以下引數。
1)auto_explain.log_min_duration(integer)
這個引數指的是最小語句執行時間,單位是毫秒,設定之後語句計劃就會被記錄。例如,設定此引數的值為250毫秒,那麼執行時間在250毫秒及以上的語句會被記錄下來。預設值為-1,表示不記錄任何計劃。
highgo=# SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; count ------- 111 (1 row) |
如果將此引數設定為0,表示記錄所有的計劃。
highgo=# SET auto_explain.log_min_duration = 0; SET highgo=# SET auto_explain.log_analyze = true; SET highgo=# SELECT count(*) highgo-# FROM pg_class, pg_index highgo-# WHERE oid = indrelid AND indisunique; 日誌: 00000: duration: 0.935 ms plan: Query Text: SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; Aggregate (cost=22.25..22.26 rows=1 width=0) (actual time=0.925..0.925 rows=1 loops=1) -> Hash Join (cost=5.75..21.98 rows=111 width=0) (actual time=0.816..0.907 rows=111 loops=1) Hash Cond: (pg_class.oid = pg_index.indrelid) -> Index Only Scan using pg_class_oid_index on pg_class (cost=0.15..12.89 rows=316 width=4) (actual time=0.731..0.782 rows=317 loops=1) Heap Fetches: 87 -> Hash (cost=4.22..4.22 rows=111 width=4) (actual time=0.046..0.046 rows=111 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 12kB -> Seq Scan on pg_index (cost=0.00..4.22 rows=111 width=4) (actual time=0.006..0.023 rows=111 loops=1) Filter: indisunique Rows Removed by Filter: 11 count ------- 111 (1 row) |
2)auto_explain.log_analyze(boolean)
設定這個引數使得當一個執行計劃被記錄時,會讓EXPLAIN ANALYZE的結果,而不僅僅是EXPLAIN 的結果被打印出來。預設值為off。
highgo=# SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; 日誌: 00000: duration: 0.131 ms plan: Query Text: SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; Aggregate (cost=22.25..22.26 rows=1 width=0) -> Hash Join (cost=5.75..21.98 rows=111 width=0) Hash Cond: (pg_class.oid = pg_index.indrelid) -> Index Only Scan using pg_class_oid_index on pg_class (cost=0.15..12.89 rows=316 width=4) -> Hash (cost=4.22..4.22 rows=111 width=4) Buckets: 1024 Batches: 1 Memory Usage: 12kB -> Seq Scan on pg_index (cost=0.00..4.22 rows=111 width=4) Filter: indisunique count ------- 111 (1 row) |
將此引數設定為on之後,就能獲得EXPLAIN ANALYZE的結果。
highgo=# SELECT count(*) highgo-# FROM pg_class, pg_index highgo-# WHERE oid = indrelid AND indisunique; 日誌: 00000: duration: 0.935 ms plan: Query Text: SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; Aggregate (cost=22.25..22.26 rows=1 width=0) (actual time=0.925..0.925 rows=1 loops=1) -> Hash Join (cost=5.75..21.98 rows=111 width=0) (actual time=0.816..0.907 rows=111 loops=1) Hash Cond: (pg_class.oid = pg_index.indrelid) -> Index Only Scan using pg_class_oid_index on pg_class (cost=0.15..12.89 rows=316 width=4) (actual time=0.731..0.782 rows=317 loops=1) Heap Fetches: 87 -> Hash (cost=4.22..4.22 rows=111 width=4) (actual time=0.046..0.046 rows=111 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 12kB -> Seq Scan on pg_index (cost=0.00..4.22 rows=111 width=4) (actual time=0.006..0.023 rows=111 loops=1) Filter: indisunique Rows Removed by Filter: 11 count ------- 111 (1 row) |
注意,將這個引數設定為on可能會對效能造成極大的不良影響,所以為了優化效能成本可以將它設定為off,代價是獲得的資訊會少一些。
3)auto_explain.log_buffers(boolean)
此引數控制著當一個執行計劃被記錄時,緩衝區用量統計資訊是否被打印出來。這個引數只有當開啟auto_explain.log_analyze後才有作用,預設為off。
將這個引數設定為on:
highgo=# SET auto_explain.log_buffers = on; SET highgo=# SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; 日誌: 00000: duration: 0.203 ms plan: Query Text: SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; Aggregate (cost=22.25..22.26 rows=1 width=0) (actual time=0.197..0.197 rows=1 loops=1) Buffers: shared hit=31 -> Hash Join (cost=5.75..21.98 rows=111 width=0) (actual time=0.059..0.188 rows=111 loops=1) Hash Cond: (pg_class.oid = pg_index.indrelid) Buffers: shared hit=31 -> Index Only Scan using pg_class_oid_index on pg_class (cost=0.15..12.89 rows=316 width=4) (actual time=0.013..0.060 rows=317 loops=1) Heap Fetches: 87 Buffers: shared hit=28 -> Hash (cost=4.22..4.22 rows=111 width=4) (actual time=0.039..0.039 rows=111 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 12kB Buffers: shared hit=3 -> Seq Scan on pg_index (cost=0.00..4.22 rows=111 width=4) (actual time=0.003..0.028 rows=111 loops=1) Filter: indisunique Rows Removed by Filter: 11 Buffers: shared hit=3 count ------- 111 (1 row) |
從結果中看到,緩衝區資訊被打印出來。
4)auto_explain.log_timing(boolean)
此引數控制著當一個執行計劃被記錄時,是否每個節點的時間資訊都被打印出來。這個引數只有當開auto_explain.log_analyze後才有作用,預設值為on。
將這個引數設定為on之後,時間資訊就不會被打印出來:
highgo=# SET auto_explain.log_timing = off; SET highgo=# SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; 日誌: 00000: duration: 0.198 ms plan: Query Text: SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; Aggregate (cost=22.25..22.26 rows=1 width=0) (actual rows=1 loops=1) Buffers: shared hit=31 -> Hash Join (cost=5.75..21.98 rows=111 width=0) (actual rows=111 loops=1) Hash Cond: (pg_class.oid = pg_index.indrelid) Buffers: shared hit=31 -> Index Only Scan using pg_class_oid_index on pg_class (cost=0.15..12.89 rows=316 width=4) (actual rows=317 loops=1) Heap Fetches: 87 Buffers: shared hit=28 -> Hash (cost=4.22..4.22 rows=111 width=4) (actual rows=111 loops=1) Buckets: 1024 Batches: 1 Memory Usage: 12kB Buffers: shared hit=3 -> Seq Scan on pg_index (cost=0.00..4.22 rows=111 width=4) (actual rows=111 loops=1) Filter: indisunique Rows Removed by Filter: 11 Buffers: shared hit=3 count ------- 111 (1 row) |
需要注意的是,在有些系統中重複讀取系統時鐘的開銷會顯著地降低查詢速率。所以如果我們只想得到實際的行數資訊,而不是精確的時間資訊的話,建議將此引數設定為off。
5)auto_explain.log_triggers(boolean)
此引數使得當一個執行計劃被記錄時,觸發器的執行統計資訊也會被包含進去。這個引數只有當開啟auto_explain.log_analyze後才有作用,預設值為off。
6)auto_explain.log_verbose(boolean)
此引數控制著當執行計劃被記錄時,是否列印細節資訊。預設值為off。
如果將此引數設定為on,就能打印出細節資訊:
highgo=# SET auto_explain.log_verbose = on; SET highgo=# SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; 日誌: 00000: duration: 0.116 ms plan: Query Text: SELECT count(*) FROM pg_class, pg_index WHERE oid = indrelid AND indisunique; Aggregate (cost=22.25..22.26 rows=1 width=0) (actual rows=1 loops=1) Output: count(*) Buffers: shared hit=31 -> Hash Join (cost=5.75..21.98 rows=111 width=0) (actual rows=111 loops=1) Hash Cond: (pg_class.oid = pg_index.indrelid) Buffers: shared hit=31 -> Index Only Scan using pg_class_oid_index on pg_catalog.pg_class (cost=0.15..12.89 rows=316 width=4) (actual rows=317 loops=1) Output: pg_class.oid Heap Fetches: 87 Buffers: shared hit=28 -> Hash (cost=4.22..4.22 rows=111 width=4) (actual rows=111 loops=1) Output: pg_index.indrelid Buckets: 1024 Batches: 1 Memory Usage: 12kB Buffers: shared hit=3 -> Seq Scan on pg_catalog.pg_index (cost=0.00..4.22 rows=111 width=4) (actual rows=111 loops=1) Output: pg_index.indrelid Filter: pg_index.indisunique Rows Removed by Filter: 11 Buffers: shared hit=3 count ------- 111 (1 row) |
更加詳細的引數設定請登入【瀚高技術支援平臺】檢視
https://support.highgo.com/#/index/docContent/a540bd27037b31e6