パフォーマンスのトラブルシューティング

パフォーマンス 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-Tree、ハッシュ、 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. データベースまたはオブジェクトが CREATE または INSERT 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 など、利用可能なメトリクスの多くは、デプロイで オートスケーリン グを 設定するのに役立ちます。 オートスケーリングはデフォルトでは有効になっていないため、手動で設定する必要があります。

使用量の傾向を観察し、その傾向に対応するようにオートスケーリングを設定することで、リソースが枯渇してデータベースが不安定になる前に、パフォーマンスの問題を軽減することができます。 例えば、ディスクI/OやCPU、メモリ障害の変化がパフォーマンス問題を引き起こす場合など。

ディスク IOPS

1秒あたりの入出力操作数(IOPS)は、ストレージボリュームの種類とサイズによって制限される。 デプロイメント Databases for PostgreSQL のストレージボリュームは、10 IOPS/GBティアの Endurance Block Storage ボリューム 上でプロビジョニングされます。

運用負荷が飽和したり、IOPSの上限を超えたりすると、ストレージサブシステムが追いつくまで、データベースのリクエストと操作は遅延する。 高負荷が長期間続くと、配置がクエリを処理できなくなり、事実上利用できなくなる可能性があります。 ディスクサイズを大きくすることで、配備で利用可能な IOPS 数を増やすことができます。 たとえば、10 IOPS/GBの階層の場合、ボリュームサイズを大きくすることでIOPSを増やすことができます。

ディスク使用率が40~50%に及ぶ状態が長期間続くと、データベースのパフォーマンスに重大な悪影響を及ぼす可能性があります。 本番環境には少なくとも100GBのディスク(1,000IOPS)を割り当てます。 IOPS = 割り当てられたGB × 10(例:100 GB = 1,000 IOPS)

メモリー使用率

メモリは、データにアクセスし処理する最も高速かつ効率的な方法である。 このため、データベースはディスクからデータを読み込むよりもメモリを使用する方が、ほぼ常に高速に動作します。 キャッシュヒット数、読み取りブロック数、ヒットブロック数など、検討すべき他の指標も存在する。 メモリ使用率が100%であること自体は、それ自体で懸念すべき事由とはならない。 メモリが枯渇しスワップページが使用されると、パフォーマンスが大幅に低下する可能性があります。

Databases for PostgreSQL、 shared_buffersを 調整することで、データベースの共有バッファプール専用のメモリ量を設定することができます。 推奨される最大値は、配備の総メモリの 25%です。 共有バッファ・プールにあまりに多くのメモリを割り当てると、他の目的のためにシステムのメモリが不足したり、パフォーマンスが低下したり、場合によってはデータベースが使用不能になったりします。

データベース負荷監視

データベースの負荷を確認するには、次の2つの方法があります:

オプション 1: 長時間実行中のクエリを確認するには、( ICL ) IBM Cloud Logs を使用します

詳細については、 「クエリ履歴を追跡するにはどうすればよいですか?」 を参照してください

以下の DataPrime サンプルクエリを. IBM Cloud Logs で使用できます。

  1. ログを読み込んだ IBM Cloud 後、タブ </>DataPrime に切り替えてください。 </>Lucene 検索バーの内容は一切変更しないでください。
  2. [ </>DataPrime タブ]から、1000ミリ秒以上実行中のSQLを検索するために以下のクエリを実行します。 また、[検索] </>DataPrime タブに貼り付けることもできます。
{

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

}

オプション 2: 有効にする 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 クエリプレビュー 呼び出し 総実行時間 pct_exec_time 実行時間の割合 平均実行時間
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 イブムクラウドベ <権限不足> 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 クエリプレビュー 呼び出し回数 pct_calls cum_pct_calls 総実行時間 平均実行時間
ibm Postgres <権限不足> 80285 23.84 24 16095.420 0.200
ibm Postgres <権限不足> 36832 10.94 34 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. 1秒あたりのクエリ数を計算する:

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

時間がかかるクエリトップ10

時間のかかるクエリの上位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 を追加する

      • ディスク/メモリをスケールアップして、より高いIOPSとメモリを実現する

  • インデックスの欠如または非効率性は、クエリの遅延の一般的な原因です。 EXPLAINを使用してシーケンシャルスキャンを特定し、インデックスの追加を検討してください。

  • データベースの健全性分析を支援するためにVACUUMを実行してください。

  • Databases for PostgreSQL は、 Databases for PostgreSQL データベースへの最大接続数を 115 に設定します。 15個の接続はデータベースの状態と整合性を維持するためにスーパーユーザー用に予約され、100個の接続はあなたとあなたのアプリケーションのために利用可能です。 接続制限に達した後、新しい接続を開始しようとするとエラーになる。 接続が原因でデプロイメントが過負荷になることを防止するには、接続プーリングを使用するか、デプロイメントをスケーリングして接続制限を引き上げてください。 詳細については、 「接続プーリング PostgreSQL の管理」 を参照してください。

  • バックアップやデータのバッチアップロードを実行しているレシピがないか確認してください。例: 自動バックアップは毎日実行され、30日間のシンプルな保持スケジュールで管理されます。 バックアップが停止している場合、データベースインスタンスのクラウドUIページで「 利用可能なバックアップ 」セクションを確認し、停止したバックアップを特定できます。

  • メンテナンスに関する通知 IBM Cloud を確認してください。 例えば、データベースのパッチ適用。

  • これがメンテナンスなどのプラットフォームの問題であると思われる場合は、データベースのCRNを添えてサポート IBM までご連絡ください。