效能疑難排解

請使用以下指引來排除效能 IBM Cloud® Databases for PostgreSQL 問題。

欲了解概況,請參閱 PostgreSQL 性能。

資料庫效能低落

此問題的典型症狀如下:

  • 高磁碟輸入/輸出 (I/O) 或記憶體使用率
  • 緩慢查詢

最常見的原因是正在檢視慢查詢。 請完成以下步驟以確認是否屬此情況:

  1. 列出長期運行的查詢:

    select age(now(),query_start), pid, client_addr, state, substring(query,0,80) from pg_stat_activity where state != 'idle' order by 1 desc;
    
  2. 驗證查詢阻塞:

    select pg_blocking_pids(pid), pid AS blocked_pid, state, query, age(now(),query_start) AS duration from pg_stat_activity where array_length(pg_blocking_pids(pid),1) > 0 order by 1,2;
    
  3. 檢查查詢執行計劃:

    Explain <query>;
    
  4. 檢查資料庫統計資料是否遺漏。 請使用以下查詢進行驗證:操作 > 執行分析 或者,執行以下命令:

    Analyze <tablename>  select relname, n_live_tup, n_dead_tup, last_vacuum,last_autovacuum,last_analyze,last_autoanalyze, analyze_count,autoanalyze_count from pg_stat_all_tables where schemaname='public';
    
  5. 檢查索引是否從表格中遺失。 PostgreSQL 提供索引方法,例如 B-樹、雜湊、SP-GiST,GiST, GIN 和 BRIN。 請使用以下任一方法建立索引。

  6. 檢查資料表是否膨脹。 執行以下查詢以進行驗證。 動作 > 執行真空

    或者,使用以下陳述:

    SELECT
    relname AS table_name,
    pg_size_pretty(pg_relation_size(c.oid)) AS actual_size,
    pg_size_pretty(
    CASE
    WHEN c.relpages = 0 THEN 0
    ELSE (pg_relation_size(c.oid) - (c.relpages *
    (current_setting('block_size')::numeric - 24))) * 100 / pg_relation_size(c.oid)
    END
    ) AS bloat_percentage, pg_size_pretty(
    CASE
    WHEN c.relpages = 0 THEN 0
    ELSE (pg_relation_size(c.oid) - (c.relpages *
    (current_setting('block_size')::numeric - 24)))
    END
    )AS bloat_size
    FROM pg_class c
    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
    WHERE relkind = 'r' AND n.nspname = 'public' -- Adjust schema if needed
    ORDER BY bloat_size DESC NULLS LAST;
    
  7. 請考慮資料庫或物件是否已使用 pg_dump 或 建立 pg_restore。 使用 「動作」>「更新統計數據」來刷新。

  8. 若查詢正在執行排序操作,請確保分配 work_mem 足夠的資源。

  9. 使用 pg_stat 陳述式來找出以下資訊:

    • 查詢平均執行時間與呼叫次數

    • 查詢所佔用的 CPU 百分比使用率

    • 查詢佔用的記憶體百分比

pg_stat_activity, pg_stat_bgwriter,以及 pg_buffercache 是 中 PostgreSQL 用於監控和理解資料庫效能的重要工具。

部署監控與資料庫負載監控

Databases for PostgreSQL 部署提供與服務 IBM Cloud Monitoring 的整合功能,用於監控您部署中的資源使用情況。 使用此服務監控您的部署(磁碟和記憶體)以及資料庫負載。

使用 Cloud Databases 儀表板設定 CPU、記憶體及磁碟 IOPS 閾值的警示。 許多現有的指標(例如磁碟使用量和 IOPS)對於協助您在部署中設定 自動擴展功能 相當有用。 自動擴展功能預設為停用狀態,因此您必須手動進行設定。

觀察使用趨勢並設定自動擴展功能以因應這些趨勢,有助於在資料庫因資源耗盡而變得不穩定之前,預先緩解效能問題。 例如,磁碟輸入輸出、CPU 或記憶體故障的變化導致效能問題。

磁碟 IOPS

每秒輸入/輸出操作數(IOPS)受儲存卷的類型與大小所限制。 部署 Databases for PostgreSQL 的儲存容量預先配置於 Block Storage 耐力卷上,採用每GB 10 IOPS的等級。

若您的運作負載達到飽和或超過 IOPS 限制,資料庫請求與操作將被延遲,直至儲存子系統能趕上進度為止。 長時間的重負載可能導致您的部署無法處理查詢,從而實際上無法使用。 您可以透過增加磁碟容量來提升部署環境的可用 IOPS 數量。 舉例來說,對於每 GB 層級為 10 IOPS 的配置,您可以透過增加卷宗大小來提升 IOPS 效能。

即使僅有40-50%的磁碟使用率持續較長時間,也可能對資料庫效能造成顯著負面影響。 為生產環境分配至少 100 GB 磁碟空間(1,000 IOPS)。 IOPS = 10 × 分配的 GB 數(例如,100 GB = 1,000 IOPS)

記憶體用量

記憶體是存取與處理資料最快捷、最高效的方式。 正因如此,資料庫使用記憶體存取資料時,幾乎總是比從磁碟讀取資料更快。 還有其他指標需要檢視與考量,例如快取命中率、讀取區塊數以及命中區塊數。 單純看到記憶體使用率達到100%本身並不足以引發擔憂。 若記憶體耗盡而需使用交換頁,效能將大幅下降。

您可透過調整設定 Databases for PostgreSQL 檔中的 shared_buffers 參數,來設定專供資料庫共享緩衝區池使用的記憶體容量。 建議的最大值為部署總記憶體的 25%。 若為共享緩衝區分配過多記憶體,可能導致系統缺乏其他用途所需的記憶體,進而影響效能,甚至可能使資料庫無法運作。

資料庫負載監控

您有兩種方式可檢查資料庫負載:

選項1. 使用 IBM Cloud Logs ( ICL ) 檢查長時間運行的查詢:

欲了解更多資訊,請參閱 《如何追蹤查詢歷史記錄?》

您可以在中使用以下 IBM Cloud Logs 範例 DataPrime 查詢。

  1. 載入日誌 IBM Cloud 後,切換至標 </>DataPrime 籤頁。 請勿變更 </>Lucene 搜尋欄中的任何內容。
  2. 從 標 </>DataPrime 籤頁,執行以下查詢以找出執行時間超過 1000 毫秒的 SQL 語句。 您亦可將其貼至「搜尋」標 </>DataPrime 籤頁中。
{

source logs|filter message.attr.durationMillis>=1000

}

選項二。 啟用 log_min_duration_statement

使用 可 log_min_duration_statement 指定將執行時間超過指定毫秒數的陳述式記錄至日誌。 如需更多資訊,請參閱 log_min_duration_statement。

您亦可安裝 pg_stat_statements 擴充套件:

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

此擴充功能可讓您查詢統計資料,找出執行時間特別長的查詢範例。 您可據此隔離問題,並考慮採用不同的查詢模式、新增或修改索引、調整表格設計,或採取其他策略來提升效能。

查詢 1:識別耗時查詢

執行以下陳述式即可找出耗時的查詢:

SELECT username, database, queryid, query_preview, calls, total_exec_time, pct_exec_time, ROUND(SUM(pct_exec_time) OVER (ORDER BY total_exec_time DESC)) AS cum_pct_exec_time, avg_exec_time FROM ( SELECT pu.usename AS username, pd.datname AS database, pss.queryid, LEFT(pss.query, 50) AS query_preview, pss.calls, ROUND(pss.total_exec_time::numeric, 3) AS total_exec_time, ROUND((100.0 * pss.total_exec_time / SUM(pss.total_exec_time) OVER ())::numeric, 2) AS pct_exec_time, ROUND(pss.mean_exec_time::numeric, 3) AS avg_exec_time FROM pg_stat_statements pss JOIN pg_user pu ON pss.userid = pu.usesysid JOIN pg_database pd ON pss.dbid = pd.oid ) AS subquery ORDER BY total_exec_time DESC LIMIT 25;

此陳述產生以下結果:

耗時查詢語句的結果
使用者名稱 資料庫 查詢ID 查詢預覽 呼叫 總執行時間 執行時間百分比 執行時間百分比 平均執行時間
IBM postgres <權限不足> 50685 38286.580 19.52 20 0.755
ibm postgres <權限不足> 280111 28477.951 14.52 34 0.102
ibm postgres <權限不足> 18 14568.978 7.43 41 809.388
ibm postgres <權限不足> 18 12103.904 6.17 48 672.439
ibm IBM Cloud DB <權限不足> 37552 7799.984 3.98 52 0.208
(5行)

此查詢追蹤 SQL 陳述式的執行統計資料,並提供以下資訊:

  • 顯示耗時最長的25項查詢
  • 顯示執行查詢的使用者、所使用的資料庫,以及查詢的預覽內容
  • 顯示每個查詢的執行頻率及其平均耗時
  • 計算每個查詢佔用總資料庫時間的百分比
  • 提供資料庫使用時間的累計總數

查詢 2:識別頻繁執行的查詢

您可透過執行以下語句來找出經常執行的查詢:

SELECT
   username,
   database,
   queryid,
   query_preview,
   calls,
   pct_calls,
   ROUND(SUM(pct_calls) OVER (ORDER BY calls DESC)) AS cum_pct_calls,
   total_exec_time,
   avg_exec_time
FROM (
   SELECT
      pu.usename AS username,
      pd.datname AS database,
      pss.queryid,
      LEFT(pss.query, 50) AS query_preview,
      pss.calls,
      ROUND(100.0 * pss.calls / SUM(pss.calls) OVER (), 2) AS pct_calls,
      ROUND(pss.total_exec_time::numeric, 3) AS total_exec_time,
      ROUND(pss.mean_exec_time::numeric, 3) AS avg_exec_time
   FROM
      pg_stat_statements pss
      JOIN pg_user pu ON pss.userid = pu.usesysid
      JOIN pg_database pd ON pss.dbid = pd.oid
) AS subquery
ORDER BY
   calls DESC
LIMIT 25;

此陳述產生以下結果:

頻繁執行查詢語句的結果
使用者名稱 資料庫 查詢ID 查詢預覽 呼叫 百分比通話 cum_pct_calls 總執行時間 平均執行時間
IBM postgres <權限不足> 80285 23.84 24 16095.420 0.200
IBM postgres <權限不足> 36832 10.94 35 548.787 0.015
IBM postgres <權限不足> 20626 6.12 41 741.755 0.036
IBM postgres <權限不足> 14702 4.36 45 23982.252 1.631
IBM postgres <權限不足> 12436 3.69 49 1750.426 0.141

此查詢提供以下資訊:

  • 顯示執行次數最多的25項查詢
  • 顯示執行查詢的使用者、所使用的資料庫,以及查詢的預覽內容
  • 顯示每個查詢的執行次數、總耗時及平均耗時
  • 計算每個查詢在所有查詢呼叫中所佔的比例
  • 提供查詢呼叫的累計總數

取得所有查詢的當前執行效能

  1. 要取得所有查詢的當前執行效能,請執行以下陳述式:

    select now() as t1,sum(total_exec_time) as et1, sum(calls) as c1 from pg_stat_statements
    

    這產生以下結果:

    所有現行查詢陳述式之執行結果
    t1 et1 c1
    2025年9月30日 08:15:43.898157 +00 104109.55454499979 336889
    (1 row)
  2. 然後等待10秒,並執行以下陳述式:

    select now() as t2,sum(total_exec_time) as et2, sum(calls) as c2 from pg_stat_statements
    

    這產生以下結果:

    select now() 語句的結果
    t2 et2 c2
    2025年9月30日 08:16:18.943609 +00 104113.70054399982 336896
    (1 row)
  3. 計算每秒查詢次數:

    Queries per second = (c2-c1)/(t2-t1) and average query performance = (et2-et1)/(c2-c1)
    

十大耗時查詢

要取得耗時最多的前10項查詢:

SELECT query, calls, total_exec_time/calls as avg_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

這產生以下結果:

| 查詢 | 呼叫 | 平均時間 |   | | -------------- | -------------- | -------------- | | <權限不足> | 14706 |   1.6311896077791408 | | <權限不足> | 80305 |   0.2004813740987463 | | <權限不足> |     6 |   800.7297508333332 | | <權限不足> |   6 |   721.1415835000001 | | <權限不足> | 10316 |   0.3907427791779766 | | <權限不足> | 10316 | 0.35429842613416024 | | <權限不足> | 10316 |   0.3184477990500202 | | <權限不足> | 10316 |   0.2285179489143081 | | <權限不足> | 12439 |   0.1407493980223488 | | <權限不足> | 10316 |   0.1605010507948812 | | (10行) | | |

您可採取的進一步行動以提升效能

您亦可考慮採取以下措施來排除效能問題:

  • 優化慢查詢

    • 對執行緩慢的查詢執行 EXPLAIN (ANALYZE, BUFFERS)。 這顯示資料庫如何執行查詢,以及查詢速度慢的地方。 例如:
    EXPLAIN (ANALYZE, BUFFERS)
    SELECT * FROM student WHERE student_id = 12345;
    
    • 尋找:

      • 佔用大量記憶體或磁碟空間的查詢

      • 按需添加 IBM Cloud 資源

      • 擴充磁碟/記憶體以提升每秒輸入輸出操作次數與記憶體容量

  • 索引遺失或效能不佳是導致查詢速度緩慢的常見原因。 使用 EXPLAIN 來識別順序掃描,並考慮添加索引。

  • 執行 VACUUM 命令以協助進行資料庫健康分析。

  • 請考慮使用連線池來處理更多連線。Databases for PostgreSQL 將資料 Databases for PostgreSQL 庫的最大連線數設定為 115。 其中 15 個連線保留給超級使用者,用於維護資料庫的狀態與完整性;其餘 100 個連線可供您與您的應用程式使用。 達到連接限制後,任何嘗試建立新連接的操作都會導致錯誤。 為避免部署因連線數量過多而不堪負荷,請採用連線池機制,或擴展部署規模並提高其連線限制。 如需更多資訊,請參閱《 管理 PostgreSQL 連線池 》。

  • 檢查是否有任何執行備份和批次上傳資料的程序,例如: 自動備份每日執行完成,並採用簡單的30天保留時程表進行保存。 若備份卡住,您可檢查「可用備份」區段,並在資料庫執行個體的雲端使用者介面頁面中識別卡住的備份。

  • 請檢查您的 IBM Cloud 通知,確認是否有任何維護作業。 例如,資料庫修補程式。

  • 若您認為此為平台問題(例如系統維護),請提供資料庫CRN編號聯繫 IBM 支援部門。