インデックスを管理するときのリレーショナル (SQL) データベースと DynamoDB の相違点
インデックスは代替のクエリパターンへのアクセスを付与し、クエリを高速化できます。このセクションでは、SQL と Amazon DynamoDB におけるインデックスの作成と使用を比較します。
リレーショナルデータベースまたは DynamoDB のいずれを使用するにしても、インデックスの作成は慎重に判断する必要があります。テーブルに書き込みが発生するたびに、テーブルのインデックスはすべて、更新する必要があります。大きなテーブルでの書き込み量が多い環境では、大量のシステムリソースを消費する可能性があります。読み取り専用または読み取りがほとんどの環境では、これは大きな問題にはなりません。ただし、インデックスがアプリケーションによって実際に使用されており、ただ容量を取っていることがないよう確認する必要があります。
トピック
インデックス作成時のリレーショナル (SQL) データベースと DynamoDB の相違点
SQL の CREATE INDEX
ステートメントを Amazon DynamoDB の UpdateTable
オペレーションと比較します。
SQL を使ってインデックスを作成する
リレーショナルデータベースのインデックスは、テーブルの異なる列に対して高速にクエリを実行できるデータ構造です。CREATE
INDEX
SQL ステートメントを使用して、既存のテーブルにインデックスが追加し、インデックスを作成する列を指定します。インデックスの作成後は、通常どおりテーブルのデータにクエリを実行できますが、テーブル全体をスキャンする代わりに、テーブルの指定された行を迅速に検索するため、データベースがインデックスを使用することができます。
インデックスの作成後は、データベースが維持します。テーブルのデータを変更した場合は、インデックスが自動的に変更され、テーブル内の変更を反映します。
MySQL では、次のようなインデックスを作成します。
CREATE INDEX GenreAndPriceIndex ON Music (genre, price);
DynamoDB でインデックスを作成する
DynamoDB では、同様の目的のために、セカンダリインデックスを作成して使用できます。
DynamoDB のインデックスはリレーショナルな対応物とは異なります。セカンダリインデックスを作成する際、そのキー属性 (パーティションキーとソートキー) を指定する必要があります。セカンダリインデックスを作成したら、テーブルと同じように Query
または Scan
を実行できます。DynamoDB にはクエリオプティマイザーがないため、セカンダリインデックスは Query
または Scan
の場合にのみ使用されます。
DynamoDB では、次の 2 種類のインデックスをサポートしています。
-
グローバルセカンダリインデックス – インデックスのプライマリキーは、テーブルからの任意の 2 つの属性になります。
-
ローカルセカンダリインデックス – インデックスのパーティションキーは、テーブルのパーティションキーと同じである必要があります。ただし、ソートキーは、他の任意の属性にすることができます。
DynamoDB を使えば、セカンダリインデックスのデータは結果的にテーブルと整合性が取れます。テーブルまたはローカルセカンダリインデックスでの強い整合性を持つ Query
または Scan
オペレーションをリクエストできます。ただし、グローバルセカンダリインデックスは結果整合性のみをサポートします。
UpdateTable
オペレーションを使用し、GlobalSecondaryIndexUpdates
を指定して、既存のテーブルにグローバルセカンダリインデックスを追加できます。
{ TableName: "Music", AttributeDefinitions:[ {AttributeName: "Genre", AttributeType: "S"}, {AttributeName: "Price", AttributeType: "N"} ], GlobalSecondaryIndexUpdates: [ { Create: { IndexName: "GenreAndPriceIndex", KeySchema: [ {AttributeName: "Genre", KeyType: "HASH"}, //Partition key {AttributeName: "Price", KeyType: "RANGE"}, //Sort key ], Projection: { "ProjectionType": "ALL" }, ProvisionedThroughput: { // Only specified if using provisioned mode "ReadCapacityUnits": 1,"WriteCapacityUnits": 1 } } } ] }
UpdateTable
に以下のパラメータを提供する必要があります。
-
TableName
– インデックスが関連付けられるテーブル。 -
AttributeDefinitions
– インデックスのキースキーマ属性用のデータ型。 -
GlobalSecondaryIndexUpdates
– 作成するインデックスに関する詳細。-
IndexName
– インデックスの名前。 -
KeySchema
– インデックスのプライマリキーに使用する属性。 -
Projection
– テーブルからインデックスにコピーされる属性。この場合、ALL
は、すべての属性がコピーされることを意味します。 -
ProvisionedThroughput (for provisioned tables)
– このインデックスに必要な 1 秒あたりの読み取り/書き込み数。(これは、テーブルのプロビジョニングされたスループット設定とは異なります。)
-
このオペレーションの一部は、テーブルから新しいインデックスにデータをバックフィリングすることを含みます。バックフィリング中、テーブルは使用可能なままになります。ただし、インデックスは Backfilling
属性が true から false に変わるまで、準備ができていません。DescribeTable
オペレーションを使用して、この属性を表示できます。
インデックスのクエリとスキャン時のリレーショナル (SQL) データベースと DynamoDB の相違点
SQL の SELECT ステートメントを使用したインデックスのクエリとスキャンを Amazon DynamoDB の Query
および Scan
オペレーションと比較します。
SQL を使ってインデックスのクエリを実行してスキャンする
リレーショナルデータベースでは、インデックスを直接使用しません。代わりに、SELECT
ステートメントの発行により、テーブルでクエリを実行し、クエリオプティマイザは任意のインデックスを利用できます。
クエリオプティマイザは、使用できるインデックスを評価し、クエリを高速化するためにそれらを使用できるかを決定するリレーショナルデータベース管理システム (RDBMS) のコンポーネントです。クエリを高速化するためにインデックスが使用できる場合、RDBMS は最初にインデックスにアクセスし、それを使用してテーブルのデータを特定します。
GenreAndPriceIndex を使用してパフォーマンスを向上できる SQL ステートメントを次に示します。ここでは、Music テーブルに十分なデータがあり、クエリオプティマイザが、テーブル全体にスキャンするのではなく、このインデックスを使用することを前提にします。
/* All of the rock songs */ SELECT * FROM Music WHERE Genre = 'Rock';
/* All of the cheap country songs */ SELECT Artist, SongTitle, Price FROM Music WHERE Genre = 'Country' AND Price < 0.50;
DynamoDB でインデックスのクエリを実行してスキャンする
DynamoDB では、テーブルに対して実行するのと同じように、インデックスに対して直接 Query
および Scan
オペレーションを実行します。DynamoDB API または PartiQL (SQL 互換のクエリ言語) を使用して、インデックスにクエリやスキャンを実行できます。TableName
と IndexName
の両方を指定する必要があります。
以下は、DynamoDB の GenreAndPriceIndex に対するいくつかのクエリです。(このインデックスのキースキーマは、ジャンルと価格で構成されています。)