View a markdown version of this page

クエリの実行が遅い - Amazon DocumentDB

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

クエリの実行が遅い

識別 - 問題を特定する

実行速度の遅いクエリは、ビジネス要件で予想される実行時間を超えるクエリです。スロークエリを構成するものの定義は、ワークロードによって異なります。プロファイラーログまたは Performance Insights を使用してスロークエリを特定できます。

  1. まだ有効になっていない場合は、プロファイラーを有効にします。プロファイラーログは、ロググループ の Amazon CloudWatch に書き込まれます/aws/docdb/<cluster-identifier>/profiler。CloudWatch Logs Insights を使用してクエリを実行します。

    ecommerce.products コレクションの 10 個の最も遅いクエリを取得するための CloudWatch ログ分析クエリの例:

    filter ns="ecommerce.products" | sort millis desc | limit 10
  2. Performance Insights を使用して、高価なクエリをほぼリアルタイムで特定します。Performance Insights がまだ有効になっていない場合は有効にします。

    1. AWS コンソールを開き、Amazon Amazon DocumentDB に移動し、Performance Insights に移動して、クラスターインスタンスを選択します。

    2. DB ロード (AAS) タイムラインと上位クエリ (DB ロード別) を確認します。クエリダイジェストを展開して、リテラル子ステートメントを表示します。

    3. 分析が必要なクエリをキャプチャします。

    注記

    Performance Insights のすべてのクエリが非効率またはスロークエリであるとは限りません。

調査 — 情報を収集する

  1. プロファイラーは、mris、nreturned、planSummary (インデックス使用状況) など、クエリ実行プランとそれに関連付けられた主要なメトリクスを提供します。

    { "op": "query", "ts": 1721374275673, "ns": "test.perf", "command": { "find": "perf", "filter": { "threadRunCount": 0 }, "$db": "test", "lsid": { "id": { "$binary": "oO2wEtpgQIK+y9KGByYnsw==", "$type": "4" } }, "$readPreference": { "mode": "secondaryPreferred" } }, "cursorExhausted": true, "nreturned": 0, "responseLength": 0, "protocol": "op_query", "millis": 137, "planSummary": "IXSCAN", "execStats": { "stage": "FETCH", "nReturned": "0", "executionTimeMillisEstimate": "100.346", "inputStage": { "stage": "IXSCAN", "nReturned": "0", "executionTimeMillisEstimate": "100.342", "indexName": "threadRunCount_1" } }, "client": "172.31.6.165:43154", "appName": "ProdAppTester14", "user": "adminuser" }

    COLLSCAN クエリを検索するには:

    filter planSummary="COLLSCAN" | sort millis desc | limit 20
  2. Performance Insights を使用して、待機、ロード、リソースへの影響 (クエリあたりの IOPS や CPU など) などのクエリ実行の傾向をリアルタイムで分析します。

    Performance Insights はクエリ実行プランを提供しないため、クエリをキャプチャし、Amazon DocumentDB クラスターのクエリで explain("executionStats") を実行します。

    db.ecommerce.products.find().explain("executionStats")
  3. 必要に応じて、プロファイラーメトリクスを Performance Insights データに関連付けます (たとえば、プロファイラーの高ミリスクエリを Performance Insights の上位クエリと一致させる)。

診断 — 根本原因を見つける

このステップでは、クエリプランを診断して、潜在的な最適化を特定します。次のフローを使用する - 症状 → 考えられる原因:

  • 症状: planSummary: "COLLSCAN"

    原因: インデックスがないか、正しくありません。

  • 症状: $group / $sort で集計が遅い

    原因: 集約パイプラインがメモリ内のデータを過剰に処理している可能性があります。

  • 症状: Performance Insights が IO 待機別にグループ化された DB Load を表示している間、レイテンシーは高くなりますが、インデックスが使用されます (planSummary: "IXSCAN")。

    原因: I/O バインドクエリ。インデックスまたはワーキングセットがインスタンスで使用可能なバッファキャッシュを超えています。

  • 症状: PI は CPU 待機状態を示し、クエリが少ないため AAS が高い

    原因: CPU バインドクエリ (複合集計、$regex)。

  • 症状: 多くのスロークエリはあるが、高価な planSummary は表示されない

    原因: 外部ボトルネック (ネットワーク、スロットリング、メンテナンスタスク、クエリの量)。

解決 — 問題を修正する

修正を実装するときは、必ず explain("executionStats") で検証し、Performance Insights DB Load をモニタリングします。

  1. planSummary: "COLLSCAN"

    • ターゲットインデックスを作成します。

      例: { category, price } でフィルタリングし、価格の降順でソートする頻繁なクエリの場合:

      db.products.createIndex({ category: 1, price: -1 })
  2. $group / $sort による集計が遅い

    • $match と $project を早期にプッシュして、$group / $sort に流れるドキュメントを減らします。

    • パイプラインの早い段階でフィールドの数を制限します。

      db.products.explain("executionStats").aggregate([ { $match: { category: "Electronics", price: { $gt: 0 } } }, // early filter { $project: { price: 1, category: 1 } }, // reduce document size { $group: { _id: "$category", avgPrice: { $avg: "$price" } } } ])
  3. Performance Insights が IO 待機別にグループ化された DB ロードを表示する間のレイテンシーが高い

    • BufferCacheHitRatio が低いか、インスタンスの ReadIOPS が高いかを検証します。インスタンスメモリを増やす (インスタンスクラスのアップグレード、例: r6g.large → r6g.xlarge) か、NVMe インスタンスクラスを使用します。

    • インデックスのフットプリントを削減します。

    • リードトラフィックをオフロードするリードレプリカを追加します (クエリが結果整合性で許容できる場合はreadPreference 設定を使用してレプリカのトラフィックをリダイレクトします)。

  4. PI は CPU 待機状態を示し、クエリが少ないため AAS が高い

    • 高価な $regex をインデックス付きプレフィックス検索または $text インデックスに置き換えます。

    • 書き込み増幅を減らすためにバッチ書き込み (挿入)。

注記

これらの変更を Production に昇格させる前に、必ずより低い環境 (非本番環境) で変更をテストしてください。