取得及分析 AlloyDB 說明計畫

您可以取得並分析執行方案,找出效能瓶頸,並最佳化 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 格式產生執行計畫。

如要產生執行計畫,請按照下列步驟操作:

  1. 將 psql 用戶端連線至執行個體
  2. 如要以文字格式產生執行計畫,請執行下列指令:

    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)
    
  3. 如要以 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 指令包含所有可用選項 (analyzeverbosecolumnar_enginecostssettingsbufferswaltimingsummary),可為指定查詢產生詳細的執行計畫 (文字或 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 TimeExecution 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 讀取的位元組數,用於維持一致性。
  • 已修改但尚未檢查點的記錄:表示已修改但尚未檢查點的記錄。

後續步驟