クエリパフォーマンスの最適化 - Amazon Quantum Ledger Database (Amazon QLDB)

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

クエリパフォーマンスの最適化

Amazon QLDB は、高性能なオンライントランザクション処理 (OLTP) ワークロードのニーズに対応することを目的としています。つまり、SQL のようなクエリ機能をサポートしているにもかかわらず、QLDB は特定のクエリパターンのセットに最適化されます。これらのクエリパターンを操作するには、アプリケーションとそのデータモデルを設計することが重要です。それ以外の場合は、テーブルが大きくなるにつれて、クエリのレイテンシー、トランザクションのタイムアウト、同時実行の競合など、重大なパフォーマンスの問題が発生します。

このセクションでは、QLDB のクエリ制約を説明し、これらの制約を考慮した最適なクエリを記述するためのガイダンスを提供します。

トランザクションタイムアウト制限

QLDB では、すべての PartiQL ステートメント (すべての SELECT クエリを含む) はトランザクションで処理され、トランザクションタイムアウト制限の対象になります。トランザクションは、コミットされるまでに最大 30 秒間実行できます。この制限を超えると、QLDB はトランザクションに対して行われたすべての作業を拒否し、トランザクションを実行するセッションを破棄します。この制限は、サービスのクライアントがトランザクションを開始し、トランザクションをコミットまたはキャンセルしないことで、セッションがリークするのを防ぎます。

同時実行の競合

QLDB では、オプティミスティック同時実行制御 (OCC) を使用して同時実行制御が実行されます。最適でないクエリは、OCC の競合が増える可能性もあります。OCC の詳細については、「Amazon QLDB 同時実行モデル」を参照してください。

最適なクエリパターン

ベストプラクティスとして、インデックス付きフィールドまたはドキュメント ID でフィルタリングする WHERE 述語句を使用してステートメントを実行することをお勧めします。QLDB では、ドキュメントを効率的に検索するために、インデックス付きフィールドに等価演算子 (= または IN) が必要です。

以下に、ユーザービューの最適なクエリパターンの例を示します。

--Indexed field (VIN) lookup using the = operator SELECT * FROM VehicleRegistration WHERE VIN = '1N4AL11D75C109151' --Indexed field (VIN) AND non-indexed field (City) lookup SELECT * FROM VehicleRegistration WHERE VIN = '1N4AL11D75C109151' AND City = 'Seattle' --Indexed field (VIN) lookup using the IN operator SELECT * FROM VehicleRegistration WHERE VIN IN ('1N4AL11D75C109151', 'KM8SRDHF6EU074761') --Document ID (r_id) lookup using the BY clause SELECT * FROM VehicleRegistration BY r_id WHERE r_id = '3Qv67yjXEwB9SjmvkuG6Cp'

これらのパターンに従わないクエリはテーブル全体のスキャンを呼び出します。テーブルスキャンは、大きなテーブルのクエリや大きな結果セットを返すクエリに対してトランザクションタイムアウトを引き起こす可能性があります。さらに、競合するトランザクションと OCC の競合につながる可能性もあります。

高基数インデックス

高基数値を含むフィールドのインデックスを作成することをお勧めします。例えば、VehicleRegistration テーブル内の VINLicensePlateNumber のフィールドは、一意にすることを意図したインデックス付きフィールドです。

ステータスコード、住所の都道府県、郵便番号などの低基数フィールドのインデックス作成は避けてください。このようなフィールドのインデックスを作成すると、クエリによって、トランザクションのタイムアウトや、意図しない OCC の競合が発生する可能性が高くなる大きな結果セットが生成される可能性があります。

コミット済みビュークエリ

コミット済みビューで実行するクエリは、ユーザービュークエリと同じ最適化ガイドラインに従います。テーブル上に作成するインデックスは、コミット済みビューのクエリにも使用されます。

履歴関数クエリ

履歴関数クエリでは、テーブルで作成するインデックスは使用されません。QLDB 履歴はドキュメント ID によってのみインデックス付けされるため、現時点では追加の履歴インデックスを作成することはできません。

ベストプラクティスとして、履歴クエリを日付範囲 (開始時刻および終了時刻) とドキュメント ID (metadata.id) の両方で修飾します。開始時刻と終了時刻を含む履歴クエリでは、日付範囲修飾のメリットが得られます。

内部結合クエリ

内部結合クエリでは、少なくとも結合の右側にあるテーブルのインデックス付きフィールドを含む結合条件を使用します。結合インデックスがない場合、結合クエリは複数のテーブルスキャンを呼び出します。結合の左側のテーブルのすべてのドキュメントに対して、クエリは右側のテーブルを完全にスキャンします。ベストプラクティスは、少なくとも 1 つのテーブルに WHERE 等価述語を指定することに加えて、結合している各テーブルにインデックス付けされているフィールドに結合することです。

例えば、次のクエリでは、VehicleRegistrationVehicle のテーブルをそれぞれの VIN フィールドに結合します。その両方にインデックスが付けられます。このクエリには、VehicleRegistration.VIN の等価述語もあります。

SELECT * FROM VehicleRegistration AS r INNER JOIN Vehicle AS v ON r.VIN = v.VIN WHERE r.VIN IN ('1N4AL11D75C109151', 'KM8SRDHF6EU074761')

結合クエリの結合基準と等価述語の両方に高基数インデックスを選択します。

回避すべきクエリパターン

次に、QLDB の大きいテーブルでは適切に拡張されない最適ではないステートメントの例をいくつか示します。クエリは最終的にトランザクションタイムアウトになるため、時間の経過とともに増加するテーブルについては、これらのタイプのクエリに依存しないことを強くお勧めします。テーブルにはサイズの異なるドキュメントが含まれているため、インデックス付けされていないクエリに対して正確な制限を定義することは困難です。

--No predicate clause SELECT * FROM Vehicle --COUNT() is not an optimized function SELECT COUNT(*) FROM Vehicle --Low-cardinality predicate SELECT * FROM Vehicle WHERE Color = 'Silver' --Inequality (>) does not qualify for indexed lookup SELECT * FROM Vehicle WHERE "Year" > 2019 --Inequality (LIKE) SELECT * FROM Vehicle WHERE VIN LIKE '1N4AL%' --Inequality (BETWEEN) SELECT SUM(PendingPenaltyTicketAmount) FROM VehicleRegistration WHERE ValidToDate BETWEEN `2020-01-01T` AND `2020-07-01T` --No predicate clause DELETE FROM Vehicle --No document id, and no date range for the history() function SELECT * FROM history(Vehicle)

一般的に、QLDB の本番ユースケースに、次のタイプのクエリパターンを実行することはお勧めしません

  • オンライン分析処理 (OLAP) クエリ

  • 述語句のない探索的クエリ

  • レポート作成クエリ

  • テキスト検索

代わりに、分析ユースケースに、最適化された目的別データベースサービスへのデータのストリーミングをすることをお勧めします。例えば、QLDB データを Amazon OpenSearch Service にストリーム配信すると、ドキュメントに対して全文検索機能を提供することができます。このユースケースを示すサンプルアプリケーションについては、GitHub リポジトリ aws-samples/amazon-qldb-streaming-amazon-opensearch-service-sample-python を参照してください。QLDB ストリーミングの詳細については、「Amazon QLDB からのジャーナルデータのストリーミング」を参照してください。

パフォーマンスのモニタリング

QLDB ドライバーは、ステートメントの結果オブジェクトで消費された I/O 使用量とタイミング情報を提供します。これらのメトリクスを使用して、非効率な PartiQL ステートメントを特定できます。詳細については、「PartiQL ステートメントの統計の取得」を参照してください。

また、Amazon CloudWatch を使用して、データオペレーションに対する台帳のパフォーマンスを追跡することもできます。指定された LedgerNameCommandType に対する CommandLatency メトリクスをモニタリングします。詳細については、「Amazon によるモニタリング CloudWatch」を参照してください。QLDB がコマンドを使用してデータオペレーションを管理する方法については、「ドライバーによるセッション管理」を参照してください。