您可以取得並分析執行方案,找出效能瓶頸,並最佳化 AlloyDB for PostgreSQL 資料庫作業。執行方案或 EXPLAIN
方案詳細說明 AlloyDB 資料庫引擎打算如何執行 SQL 查詢。執行計畫包含節點樹狀結構,其中列出 AlloyDB 資料庫為擷取所要求資料而執行的作業順序,例如資料表掃描、聯結、排序和匯總。這項計畫中的每個步驟都稱為「節點」。
執行計畫是透過 EXPLAIN
指令取得,這個指令會傳回 AlloyDB 查詢規劃工具為指定 SQL 陳述式產生的計畫。查詢規劃工具 (又稱最佳化工具) 會判斷執行指定 SQL 查詢最有效率的方式。
執行計畫包含下列元件:
- 計畫節點:代表查詢執行作業中的不同步驟,例如掃描、聯結或排序作業。
- 執行時間:EXPLAIN 方案會列出每個步驟的預估或實際執行時間,協助您找出資料庫瓶頸。
- 緩衝區用量:顯示從磁碟讀取的資料量與快取讀取的資料量,有助於找出磁碟讀取問題。
- 參數設定:方案會顯示查詢執行期間有效的參數設定。
PostgreSQL (以及 AlloyDB) 支援下列陳述式的執行計畫:
SELECT
INSERT
UPDATE
DECLARE CURSOR
CREATE AS
CREATE MATERIALIZED VIEW
REFRESH MATERIALIZED VIEW
EXECUTE
事前準備
您必須擁有 AlloyDB 叢集和執行個體。詳情請參閱「建立叢集及其主要執行個體」。
產生執行計畫
您可以從用戶端應用程式 (例如 psql、pgAdmin 或 DBeaver) 產生執行計畫。AlloyDB 支援以文字或 JSON 格式產生執行計畫。
如要產生執行計畫,請按照下列步驟操作:
- 將 psql 用戶端連線至執行個體。
如要以文字格式產生執行計畫,請執行下列指令:
SET enable_ultra_fast_cache_explain_output TO ON; /* AlloyDB Specific Command */ EXPLAIN (analyze, verbose, columnar_engine, costs, settings, buffers, wal, timing, summary, format text)
如要以 JSON 格式產生執行計畫,請執行下列指令:
SET enable_ultra_fast_cache_explain_output TO ON; /* AlloyDB Specific Command */ EXPLAIN (analyze, verbose, columnar_engine, costs, settings, buffers, wal, timing, summary, format json)
EXPLAIN
指令包含所有可用選項 (analyze
、verbose
、columnar_engine
、costs
、settings
、buffers
、wal
、timing
和summary
),可為指定查詢產生詳細的執行計畫 (文字或 JSON 格式)。analyze
選項表示系統會執行查詢,提供實際執行階段統計資料和查詢規劃工具的預估值。
查看及分析 EXPLAIN 方案資料
取得執行計畫後,即可查看及分析結果。
根據預設,EXPLAIN
輸出內容會顯示伺服器端查詢活動。如要測量端對端來回時間,請在 psql 中使用 /timing
選項,並將結果傾印至 /dev/null
。
如要查看產生的執行計畫,請在 SQL 查詢前使用 EXPLAIN
指令。
EXPLAIN SELECT...
:顯示最佳化工具在不執行查詢的情況下會選擇的計畫。EXPLAIN ANALYZE SELECT...
:執行查詢並顯示預測的計畫和實際執行統計資料,包括實際執行時間和列數。
EXPLAIN (不含 ANALYZE)
如要顯示查詢規劃工具估算的查詢費用,請執行不含 ANALYZE
選項的 EXPLAIN
陳述式。
(postgres@10.3.1.17:5432) [postgres] > EXPLAIN select * from public.index_advisor_test;
QUERY PLAN
---------------------------------------------------------------------------------
Seq Scan on index_advisor_test (cost=0.00..1735481.00 rows=100000000 width=27)
AlloyDB query id: 7588555592527881263
AlloyDB plan id: 16134093550604823483
(3 rows)
企劃書輸出內容包含下列資料:
- cost = 0.00..1735481.00:第一個數字表示擷取第一列的費用。第二個數字代表擷取最後一列的費用。
- rows = 100000000:這是查詢傳回的預估資料列數。
- width = 27:這是傳回資料列的預估寬度,有助於瞭解存取的區塊。
「分析」選項
如要顯示實際執行統計資料和執行預估值,請新增 ANALYZE
選項
(postgres@10.3.1.17:5432) [postgres] > EXPLAIN (ANALYZE) select * from public.index_advisor_test;
QUERY PLAN
---------------------------------------------------------------------------------
Seq Scan on index_advisor_test (cost=0.00..1735481.00 rows=100000000 width=27) (actual time=0.165..9342.424 rows=100000001 loops=1)
Planning Time: 0.025 ms
Execution Time: 13674.794 ms
AlloyDB query id: 7588555592527881263
AlloyDB plan id: 16134093550604823483
(5 rows)
企劃書輸出內容包含下列資料:
- 實際時間 (以毫秒為單位) = 0.165..9342.424:這會顯示傳回第一列的實際時間,以及傳回所有列的總時間。
- rows = 100000001:這是實際傳回的列數。
- loops = 1:這個值對巢狀迴圈節點很重要。如果
loops
大於 1,系統會顯示每個迴圈的平均時間。 - 規劃時間:0.025 毫秒:表示規劃工具判斷執行路徑所用的時間。
- 執行時間:13674.794 毫秒:表示規劃工具判斷路徑後,執行作業所花費的時間。
- 總執行時間:
Planning Time
和Execution Time
的總和。(0.025 + 13674.794 = 13674.819)
VERBOSE 選項
如要在執行計畫中新增更多資訊,請使用 VERBOSE
選項。在下列範例中,使用 VERBOSE
會將結構定義資格新增至資料表名稱,並顯示內部查詢 ID,可用於將查詢與其他監控工具建立關聯。
(postgres@10.3.1.17:5432) [postgres] > EXPLAIN (ANALYZE,VERBOSE) select * from public.index_advisor_test;
QUERY PLAN
---------------------------------------------------------------------------------
Seq Scan on public.index_advisor_test (cost=0.00..1735481.00 rows=100000000 width=27) (actual time=0.164..6568.938 rows=100000001 loops=1)
Output: id, value, product_id, effective_date
Query Identifier: -5175350694118300766
Planning Time: 0.027 ms
Execution Time: 10875.894 ms
AlloyDB query id: 7588555592527881263
AlloyDB plan id: 16134093550604823483
企劃書輸出內容包含下列資料:
- 輸出節點:列出查詢中包含的資料欄。如果規劃工具判斷保留某些資料欄的成本較低,有時會納入比要求更多的資料欄。
- 查詢 ID:對應至
pg_stat_statements
的 PostgreSQL ID。 - AlloyDB 查詢 ID:可用於關聯查詢洞察資訊的 AlloyDB 查詢 ID
「資料欄引擎」選項
如要顯示 AlloyDB 資料欄引擎的資訊,請新增 COLUMNAR_ENGINE
選項。
如果直欄引擎中沒有表格,請參閱下列說明計畫中的「直欄檢查」欄,瞭解狀態。
(postgres@10.3.1.17:5432) [postgres] > EXPLAIN (ANALYZE,VERBOSE, COLUMNAR_ENGINE) select * from public.index_advisor_test;
QUERY PLAN
---------------------------------------------------------------------------------
Seq Scan on public.index_advisor_test (cost=0.00..1735481.00 rows=100000000 width=27) (actual time=0.009..6328.154 rows=100000001 loops=1)
Output: id, value, product_id, effective_date
Columnar Check: table is not in the columnar store
Query Identifier: -5175350694118300766
Planning Time: 0.027 ms
Execution Time: 10673.310 ms
AlloyDB query id: 7588555592527881263
AlloyDB plan id: 16134093550604823483
如果資料表位於資料欄引擎中,且使用資料欄,系統會顯示「自訂掃描」,以及資料欄引擎的使用統計資料。
(postgres@10.3.1.17:5432) [postgres] > EXPLAIN (ANALYZE,VERBOSE, COLUMNAR_ENGINE) select * from public.index_advisor_test where product_id = 1;
QUERY PLAN
---------------------------------------------------------------------------------
Append (cost=20.00..27438.78 rows=1166668 width=27) (actual time=0.066..377.029 rows=1000290 loops=1)
-> Custom Scan (columnar scan) on public.index_advisor_test (cost=20.00..27437.66 rows=1166667 width=27) (actual time=0.065..296.904 rows=1000290 loops=1)
Output: id, value, product_id, effective_date
Filter: (index_advisor_test.product_id = 1)
Rows Removed by Columnar Filter: 98999711
Bytes fetched from storage cache: 774835915
Columnar cache search mode: native
Swap-in Time: 92.708 ms
-> Seq Scan on public.index_advisor_test (cost=0.00..1.11 rows=1 width=27) (never executed)
Output: id, value, product_id, effective_date
Filter: (index_advisor_test.product_id = 1)
Query Identifier: -4660018746142248761
Planning Time: 0.217 ms
Execution Time: 421.114 ms
AlloyDB query id: 13855683355620344431
AlloyDB plan id: 2126918133221480510
企劃書輸出內容包含下列資料:
- 查詢篩選器 (述詞):顯示您套用的篩選器 (如有)。
- 依欄篩選器移除的列:這表示依欄篩選器移除的列數。
- 從儲存空間快取擷取的位元組:顯示從儲存空間快取擷取的位元組數量。
- 換入時間:如果關係不適合記憶體,這是從直欄溢出快取 (SSD) 交換資料所需的時間。
「設定」選項
如要顯示規劃工具使用的任何非預設工作階段、資料庫或全域設定,請新增 SETTINGS
選項。
(postgres@10.3.1.17:5432) [postgres] > EXPLAIN (ANALYZE,VERBOSE, COLUMNAR_ENGINE,COSTS,SETTINGS) select * from public.index_advisor_test;
QUERY PLAN
---------------------------------------------------------------------------------
Seq Scan on public.index_advisor_test (cost=0.00..1735481.00 rows=100000000 width=27) (actual time=0.007..6366.249 rows=100000001 loops=1)
Output: id, value, product_id, effective_date
Columnar Check: table is not in the columnar store
Settings: effective_cache_size = '19690120kB', random_page_cost = '1.1', work_mem = '256MB'
Query Identifier: -5175350694118300766
Planning Time: 0.027 ms
Execution Time: 10727.068 ms
AlloyDB query id: 7588555592527881263
AlloyDB plan id: 16134093550604823483
BUFFERS 選項
如要顯示資料來源的相關資訊,請使用 BUFFERS
關鍵字。BUFFERS
數量是從所有步驟累計而來,而不只是方案中的特定步驟。
(postgres@10.3.1.17:5432) [postgres] > EXPLAIN (ANALYZE,VERBOSE, COLUMNAR_ENGINE,COSTS,SETTINGS, BUFFERS) select * from public.effective_io_concurrency_test;
QUERY PLAN
---------------------------------------------------------------------------------
Seq Scan on public.effective_io_concurrency_test (cost=0.00..1844356.96 rows=100058296 width=31) (actual time=0.111..10007.193 rows=100000001 loops=1)
Output: id, value, product_id, effective_date
Buffers: shared hit=1185 read=842625 dirtied=1, ultra fast cache hit=842625
I/O Timings: shared read=2588.597
Columnar Check: table is not in the columnar store
Settings: effective_cache_size = '19690120kB', random_page_cost = '1.1', work_mem = '256MB'
Query Identifier: -5987221491374921441
Planning:
Buffers: shared hit=58 read=2, ultra fast cache hit=2
I/O Timings: shared read=0.215
Planning Time: 0.410 ms
Execution Time: 14825.271 ms
AlloyDB query id: 12754549874439071326
AlloyDB plan id: 13656575252012920931
緩衝區資訊包括:
- 共用命中:PostgreSQL 主要共用緩衝區快取中找到的 8kB 資料區塊數量。
- 共用讀取:從作業系統讀取的 8 kB 資料區塊數。這通常表示磁碟 I/O。
- dirtied:查詢變更的先前未修改區塊數量 (可見度地圖變更)。
- 寫入:這個後端在查詢處理期間,從快取逐出的先前已變更區塊數量,通常是因為提示位元或可見度地圖變更,並排清至磁碟。
- 極速快取命中:從極速快取擷取的區塊數。
- I/O Timings:任何磁碟或 SSD I/O 的時間長度 (以毫秒為單位)。
- 規劃:在規劃階段緩衝處理活動,例如從目錄表格讀取中繼資料或統計資料。
- 規劃期間的 I/O 耗用時間:如果需要從磁碟讀取任何中繼資料,系統會顯示 I/O 時間。
預寫記錄選項
如要提供預寫記錄 (WAL) 活動的相關資訊,請使用 WAL
選項。
(postgres@10.3.1.17:5432) [postgres] > EXPLAIN (ANALYZE,VERBOSE, COLUMNAR_ENGINE,COSTS,SETTINGS, BUFFERS, WAL) select * from public.effective_io_concurrency_test;
QUERY PLAN
---------------------------------------------------------------------------------
Seq Scan on public.effective_io_concurrency_test (cost=0.00..1844356.96 rows=100058296 width=31) (actual time=0.010..10147.314 rows=100000001 loops=1)
Output: id, value, product_id, effective_date
Buffers: shared hit=1185 read=842625 dirtied=1, ultra fast cache hit=842625
I/O Timings: shared read=2590.410
WAL: records=18 bytes=5178
Columnar Check: table is not in the columnar store
Settings: effective_cache_size = '19690120kB', random_page_cost = '1.1', work_mem = '256MB'
Query Identifier: -5987221491374921441
Planning Time: 0.030 ms
Execution Time: 15033.004 ms
AlloyDB query id: 12754549874439071326
AlloyDB plan id: 13656575252012920931
WAL 資訊包括:
- WAL 記錄:為維持一致性而讀取的 WAL 記錄數。
- WAL 位元組:從 WAL 讀取的位元組數,用於維持一致性。
- 已修改但尚未檢查點的記錄:表示已修改但尚未檢查點的記錄。
後續步驟
- 瞭解執行計畫節點類型。