本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
索引提供您替代的查詢模式,可加速查詢。本節會比較及比對 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 支援兩種不同的索引:
-
全域次要索引:索引的主索引鍵可以是資料表中任兩個屬性。
-
本機次要索引:索引的分割區索引鍵必須與資料表的分割區索引鍵相同。但是,排序索引鍵可以是其他任何屬性。
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)
:此索引所需的每秒讀取及寫入數。(這和資料表的佈建輸送量設定是分開的。)
-
部分此操作會涉及將資料表中的資料回填到新的索引。在回填過程中,資料表仍可使用。但是,在索引的 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 的部分查詢。(此索引的索引鍵結構描述包含 Genre 和 Price)。
// All of the rock songs { TableName: "Music", IndexName: "GenreAndPriceIndex", KeyConditionExpression: "Genre = :genre", ExpressionAttributeValues: { ":genre": "Rock" }, };
此範例使用 ProjectionExpression
指出您只想要在結果中顯示部分屬性,而非所有屬性。
// All of the cheap country songs { TableName: "Music", IndexName: "GenreAndPriceIndex", KeyConditionExpression: "Genre = :genre and Price < :price", ExpressionAttributeValues: { ":genre": "Country", ":price": 0.50 }, ProjectionExpression: "Artist, SongTitle, Price" };
下列是對 GenreAndPriceIndex 執行的掃描。
// Return all of the data in the index { TableName: "Music", IndexName: "GenreAndPriceIndex" }