Improving Data Access with Secondary Indexes in DynamoDB
For efficient access to data in a table, Amazon DynamoDB creates and maintains indexes for the
primary key attributes. This allows applications to quickly retrieve data by specifying
primary key values. However, many applications might benefit from having one or more
secondary (or alternate) keys available, to allow efficient access to data with attributes
other than the primary key. To address this, you can create one or more secondary indexes on
a table, and issue
Scan requests against these indexes.
A secondary index is a data structure that contains a subset of attributes from
a table, along with an alternate key to support
Query operations. With
a secondary index, queries are no longer restricted to the table primary key; you can also retrieve the
data using the alternate key defined by the secondary index. A table can have multiple secondary indexes, which
gives your applications access to many different query patterns.
The data in a secondary index consists of attributes that are projected, or copied, from the table into the index. When you create a secondary index, you define the alternate key for the index, along with any other attributes that you want to be projected in the index. DynamoDB copies these attributes into the index, along with the primary key attributes from the table. You can then query or scan the index just as you would query or scan a table.
Every secondary index is automatically maintained by DynamoDB. When you add, modify, or delete items in the table, any indexes on the table are also updated to reflect these changes.
DynamoDB supports two types of secondary indexes:
Global secondary index — an index with a partition key and a sort key that can be different from those on the table. A global secondary index is considered "global" because queries on the index can span all of the data in a table, across all partitions.
Local secondary index — an index that has the same partition key as the table, but a different sort key. A local secondary index is "local" in the sense that every partition of a local secondary index is scoped to a table partition that has the same partition key value.
You should consider your application's requirements when you determine which type of index to use. The following table shows the main differences between a global secondary index and a local secondary index:
|Characteristic||Global Secondary Index||Local Secondary Index|
|Key Schema||The primary key of a global secondary index can be either simple (partition key) or composite (partition key and sort key).||The primary key of a local secondary index must be composite (partition key and sort key).|
|Key Attributes||The index partition key and sort key (if present) can be any table attributes of type string, number, or binary.||The partition key of the index is the same attribute as the partition key of the table. The sort key can be any table attribute of type string, number, or binary.|
|Size Restrictions Per Partition Key Value||There are no size restrictions for global secondary indexes.||For each partition key value, the total size of all indexed items must be 10 GB or less.|
|Online Index Operations||Global secondary indexes can be created at the same time that you create a table. You can also add a new global secondary index to an existing table, or delete an existing global secondary index. For more information, see Managing Global Secondary Indexes.||Local secondary indexes are created at the same time that you create a table. You cannot add a local secondary index to an existing table, nor can you delete any local secondary indexes that currently exist.|
|Queries and Partitions||A global secondary index lets you query over the entire table, across all partitions.||A local secondary index lets you query over a single partition, as specified by the partition key value in the query.|
|Read Consistency||Queries on global secondary indexes support eventual consistency only.||When you query a local secondary index, you can choose either eventual consistency or strong consistency.|
|Provisioned Throughput Consumption||Every global secondary index has its own provisioned throughput settings for read and write activity. Queries or scans on a global secondary index consume capacity units from the index, not from the table. The same holds true for global secondary index updates due to table writes.||Queries or scans on a local secondary index consume read capacity units from the table. When you write to a table, its local secondary indexes are also updated; these updates consume write capacity units from the table.|
|Projected Attributes||With global secondary index queries or scans, you can only request the attributes that are projected into the index. DynamoDB will not fetch any attributes from the table.||If you query or scan a local secondary index, you can request attributes that are not projected in to the index. DynamoDB will automatically fetch those attributes from the table.|
If you want to create more than one table with secondary indexes, you must do so sequentially. For
example, you would create the first table and wait for it to become
ACTIVE, create the next table and wait for it to become
ACTIVE, and so on. If you attempt to concurrently create more than
one table with a secondary index, DynamoDB will return a
For each secondary index, you must specify the following:
The type of index to be created – either a global secondary index or a local secondary index.
A name for the index. The naming rules for indexes are the same as those for tables, as listed in Limits in DynamoDB. The name must be unique for the table it is associated with, but you can use the same name for indexes that are associated with different tables.
The key schema for the index. Every attribute in the index key schema must be a top-level attribute of type String, Number, or Binary. Other data types, including documents and sets, are not allowed. Other requirements for the key schema depend on the type of index:
For a global secondary index, the partition key can be any scalar table attribute. A sort key is optional, and it too can be any scalar table attribute.
For a local secondary index, the partition key must be the same as the table's partition key, and the sort key must be a non-key table attribute.
Additional attributes, if any, to project from the table into the index. These attributes are in addition to the table key attributes, which are automatically projected into every index. You can project attributes of any data type, including scalars, documents, and sets.
The provisioned throughput settings for the index, if necessary:
For a global secondary index, you must specify read and write capacity unit settings. These provisioned throughput settings are independent of the table's settings.
For a local secondary index, you do not need to specify read and write capacity unit settings. Any read and write operations on a local secondary index draw from the provisioned throughput settings of its parent table.
For maximum query flexibility, you can create up to 5 global secondary indexes and up to 5 local secondary indexes per table.
To get a detailed listing of secondary indexes on a table, use the DescribeTable action.
DescribeTable will return the name, storage size and item counts
for every secondary index on the table. These values are not updated in real time, but they are
refreshed approximately every six hours.
You can access the data in a secondary index using either the
Scan operation. You must specify the name of the table and the name
of the index that you want to use, the attributes to be returned in the results, and
any condition expressions or filters that you want to apply. DynamoDB can return the results in ascending or
When you delete the table, all of the indexes associated with that table are also deleted.