dynamodbのスキャンとクエリの違いは何ですか?スキャン/クエリを使用する場合


85

DynamoDbドキュメントで指定されているクエリ操作:

クエリ操作は、主キー属性値のみを検索し、キー属性値の比較演算子のサブセットをサポートして、検索プロセスを絞り込みます。

およびスキャン操作:

スキャン操作は、テーブル全体をスキャンします。完全なスキャン後に返される値を絞り込むために、結果に適用するフィルターを指定できます。

これは、パフォーマンスとコストの考慮事項に基づいて最適です。

回答:


55

Dynamodbテーブルを作成するときは、プライマリキーとローカルセカンダリインデックス(LSI)を選択して、クエリ操作で必要なアイテムが返されるようにします。

クエリ操作は、主キーの同等の演算子評価のみをサポートしますが、ソートキーの条件付き(=、<、<=、>、> =、Between、Begin)をサポートします。

スキャン操作は、要求しているアイテムを取得するためにテーブル内の各アイテムを反復処理する必要があるため、一般に低速でコストがかかります。

例:

Table: CustomerId, AccountType, Country, LastPurchase

Primary Key: CustomerId + AccountType

この例では、クエリ操作を使用して以下を取得できます。

  1. AccountTypeに条件付きフィルターを設定したCustomerId

以下を返すには、スキャン操作を使用する必要があります。

  1. 特定のAccountTypeを持つすべての顧客
  2. 国別の条件付きフィルターに基づくアイテム、つまり米国のすべての顧客
  3. LastPurchaseによる条件付きフィルターに基づくアイテム、つまり先月購入したすべての顧客

ローカルセカンダリインデックス(LSI)またはグローバルセカンダリインデックス(GSI)を作成する、頻繁に使用される操作でのスキャン操作を回避するため。

例:

Table: CustomerId, AccountType, Country, LastPurchase

Primary Key: CustomerId + AccountType
GSI: AccountType + CustomerId
LSI: CustomerId + LastPurchase

この例では、クエリ操作で次のことができます。

  1. AccountTypeに条件付きフィルターを設定したCustomerId
  2. [GSI]特定のAccountTypeのCustomerIdsの条件付きフィルター
  3. [LSI] LastPurchaseに条件付きフィルターを設定したCustomerId

1
主キーの場合:CustomerId + AccountType(CustomerIDがパーティションキーであり、AccountTypeがソートキーであることを理解しています)クエリ操作は、CustomerIDまたはCustomerID + AccountTypeでのみ実行できると思います。AccountTypeのみで検索すると、スキャンになります
Adil 2018

1
@Adilに感謝します。あなたは正しいです、私はこれを反映するために私の答えを編集しました。
キンマン


34

dynamodbテーブルパーティションキー/プライマリキーをとして持っていますcustomer_country。クエリを使用する場合、customer_countryはクエリ操作を行うための必須フィールドです。すべてのフィルターは、に属するアイテムのみを作成できますcustomer_country

テーブルスキャンを実行すると、すべてのパーティションキー/主キーに対してフィルターが実行されます。まず、すべてのデータをフェッチし、テーブルからフェッチした後にフィルターを適用します。

例えば:

これcustomer_countryパーティションキー/プライマリキーidsort_keyです

-----------------------------------

customer_country | name   | id

-----------------------------------
VV               | Tom    | 1

VV               | Jack   | 2

VV               | Mary   | 4

BB               | Nancy  | 5

BB               | Lom    | 6

BB               | XX     | 7

CC               | YY     | 8

CC               | ZZ     | 9

------------------------------------
  • クエリ操作を実行すると、customer_country値にのみ適用されます。値は等しい演算子(=)のみである必要があります。

  • したがって、そのパーティションキー/主キーの値に等しいアイテムのみがフェッチされます。

  • スキャン操作を実行すると、そのテーブル内のすべてのアイテムがフェッチされ、そのデータを取得した後にデータが除外されます。

注: RCUを超えるスキャン操作は実行しないでください。


あなたの答えの出所を述べてもらえますか?
AlikElzin-kilaka 2018


10

クエリはスキャンよりもはるかに優れています-パフォーマンスの面で。scanは、その名前が示すように、テーブル全体をスキャンします。ただし、クエリを使用できることを知るには、テーブルキー、並べ替えキー、インデックス、および関連する並べ替えインデックスをよく知っている必要があります。以下を使用してクエリをフィルタリングする場合:

  • キー
  • キーとキーの並べ替え
  • インデックス
  • インデックスとそれに関連するソートキー

クエリを使用してください!それ以外の場合は、フィルタリングできる列についてより柔軟なスキャンを使用します。

次の場合はクエリできません。

  • フィルタ内の2つ以上のフィールド(キー、ソート、インデックスなど)
  • (主キーまたはインデックスの)ソートキーのみ
  • 通常のフィールド(キー、インデックス、ソートではありません)
  • インデックスとソートの混合(index1とindex2のソート)\
  • ..。

良い説明:https://medium.com/@amos.shahar/dynamodb-query-vs-scan-sql-syntax-and-join-tables-part-1-371288a7cb8f


9

パフォーマンスの観点から、アプリケーションが使用するQuery代わりにテーブルを設計することをお勧めしますScan。スキャン操作は、必要な値を除外する前に常にテーブル全体をスキャンするため、読み取り、書き込み、削除などのデータ操作を処理するためにより多くの時間とスペースが必要になります。詳しくは公式資料をご覧ください


7

リレーショナルデータベースと同様です。

取得queryあなたが主キーを使用しているwhere状態を、計算の複雑さがありますlog(n)キー構造のほとんどは、バイナリツリーであるとして。

scanクエリを実行している間は、テーブル全体をスキャンしてから、すべてにフィルターを適用しrowて正しい結果を見つける必要があります。パフォーマンスはO(n)です。テーブルが大きい場合は、はるかに遅くなります。

つまり、get主キーがわかっている場合は使用してみてください。のみscanだけ最悪のケースのために。

また、パフォーマンス目標を達成するために、さまざまなキーでさまざまな種類のクエリをサポートするグローバルセカンダリインデックスについて考えてください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.