В чем разница между сканированием и запросом в Dynamodb? Когда использовать сканирование / запрос?

85

Операция запроса, как указано в документации DynamoDb:

Операция запроса выполняет поиск только значений атрибутов первичного ключа и поддерживает подмножество операторов сравнения для значений атрибутов ключа для уточнения процесса поиска.

и операция сканирования:

Операция сканирования сканирует всю таблицу. Вы можете указать фильтры, которые будут применяться к результатам, чтобы уточнить возвращаемые вам значения после полного сканирования.

Что лучше всего на основе соображений производительности и стоимости.

Самсон
источник

Ответы:

55

При создании таблицы Dynamodb выберите «Первичные ключи» и «Локальные вторичные индексы» (LSI), чтобы операция запроса возвращала нужные элементы.

Операции запроса поддерживают только оценку оператора равенства для первичного ключа, но с условием (=, <, <=,>,> =, между, начало) для ключа сортировки.

Операции сканирования обычно медленнее и дороже, так как операция должна проходить через каждый элемент в вашей таблице, чтобы получить элементы, которые вы запрашиваете.

Пример:

Table: CustomerId, AccountType, Country, LastPurchase

Primary Key: CustomerId + AccountType

В этом примере вы можете использовать операцию запроса, чтобы получить:

  1. CustomerId с условным фильтром по AccountType

Для возврата необходимо использовать операцию сканирования:

  1. Все клиенты с определенным типом учетной записи
  2. Товары основаны на условных фильтрах по странам, т.е. все клиенты из США.
  3. Товары, основанные на условных фильтрах по LastPurchase, то есть всем клиентам, совершившим покупку в прошлом месяце.

Чтобы избежать операций сканирования при часто используемых операциях, создавая локальный вторичный индекс (LSI) или глобальный вторичный индекс (GSI).

Пример:

Table: CustomerId, AccountType, Country, LastPurchase

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

В этом примере операция запроса может позволить вам получить:

  1. CustomerId с условным фильтром по AccountType
  2. [GSI] Условный фильтр CustomerIds для определенного AccountType.
  3. [LSI] CustomerId с условным фильтром для LastPurchase.
Кинман
источник
1
если первичный ключ: CustomerId + AccountType (я понимаю, что CustomerID является ключом раздела, а AccountType - ключом сортировки), я думаю, вы можете выполнять операцию запроса только по CustomerID или по CustomerID + AccountType. Если вы будете искать только по AccountType, это будет сканирование
Адиль
1
Спасибо @Adil. Вы правы, я отредактировал свой ответ, чтобы отразить это.
Kinman
34

У вас есть ключ / первичный ключ раздела таблицы Dynamodb как customer_country. Если вы используете запрос, customer_countryэто обязательное поле для выполнения операции запроса. Все фильтры можно делать только по предметам, принадлежащимcustomer_country .

Если вы выполните сканирование таблицы, фильтр будет выполняться для всех ключей раздела / первичного ключа. Сначала он извлекает все данные и применяет фильтр после выборки из таблицы.

например:

здесь customer_countryявляется ключевым раздел / первичный ключ и idявляется sort_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.

ОК200
источник
Вы можете указать источник своего ответа?
AlikElzin-kilaka
2
@ AlikElzin-kilaka Источник: docs.aws.amazon.com/amazondynamodb/latest/developerguide/…
OK200,
10

Запрос намного лучше сканирования - с точки зрения производительности. scan, как следует из названия, будет сканировать всю таблицу. Но вы должны хорошо знать ключ таблицы, ключ сортировки, индексы и связанные с ними индексы сортировки, чтобы знать, что вы можете использовать запрос. если вы фильтруете свой запрос, используя:

  • ключ
  • ключ и сортировка ключей
  • индекс
  • index и связанный с ним ключ сортировки

используйте Query! в противном случае используйте сканирование, которое позволяет более гибко определять, какие столбцы можно фильтровать.

вы НЕ можете запрашивать, если:

  • более 2 полей в фильтре (например, ключ, сортировка и индекс)
  • только ключ сортировки (первичного ключа или индекса)
  • обычные поля (не ключевые, индексные или сортированные)
  • смешанный индекс и сортировка (index1 с сортировкой index2) \
  • ...

хорошее объяснение: https://medium.com/@amos.shahar/dynamodb-query-vs-scan-sql-syntax-and-join-tables-part-1-371288a7cb8f

Открыть Voip
источник
9

С точки зрения производительности, я считаю хорошей практикой создавать таблицу для приложений, которые будут использовать Queryвместо нее Scan. Поскольку операция сканирования всегда сканирует всю таблицу, прежде чем отфильтровать желаемые значения, это означает, что требуется больше времени и места для обработки таких операций с данными, как чтение, запись и удаление. Для получения дополнительной информации обратитесь к официальному документу

Лютон Чен
источник
7

Аналогично реляционной базе данных.

Получите, что queryвы используете первичный ключ в whereусловии, сложность вычисленийlog(n) что большая часть структуры ключа представляет собой двоичное дерево.

во время scanзапроса вы должны сканировать всю таблицу, а затем применять фильтр к каждой, rowчтобы найти правильный результат. Спектакль есть O(n). Это намного медленнее, если ваш стол большой.

Короче, попробуйте использовать, getесли знаете первичный ключ. толькоscan в худшем случае.

Кроме того, подумайте о глобальном вторичном индексе для поддержки разных типов запросов по разным ключам, чтобы повысить производительность.

Джои Транг
источник