У чому різниця між скануванням та запитом у dynamodb? Коли використовувати сканування / запит?


84

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

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

та операція сканування:

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

Що найкраще базується на оцінці ефективності та витрат.

Відповіді:


53

При створенні таблиці Dynamodb виберіть Первинні ключі та Локальні вторинні індекси (LSI), щоб операція Запит повертала потрібні Вам елементи.

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

Операції сканування, як правило, повільніші та дорожчі, оскільки операція повинна перебирати кожен елемент у вашій таблиці, щоб отримати елементи, які ви вимагаєте.

Приклад:

Table: CustomerId, AccountType, Country, LastPurchase

Primary Key: CustomerId + AccountType

У цьому прикладі ви можете використовувати операцію запиту, щоб отримати:

  1. Ідентифікатор клієнта з умовним фільтром на AccountType

Потрібно використовувати операцію сканування для повернення:

  1. Усі Клієнти з певним Типом рахунку
  2. Товари на основі умовних фільтрів за країнами, тобто для всіх клієнтів із США
  3. Товари на основі умовних фільтрів LastPurchase, тобто всіх клієнтів, які здійснили покупку за останній місяць

Щоб уникнути операцій сканування часто використовуваних операцій, створюйте Локальний вторинний індекс (LSI) або Глобальний вторинний індекс (GSI).

Приклад:

Table: CustomerId, AccountType, Country, LastPurchase

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

У цьому прикладі операція запиту може дозволити вам отримати:

  1. Ідентифікатор клієнта з умовним фільтром на AccountType
  2. [GSI] Умовний фільтр за ідентифікаторами клієнтів для певного типу AccountType
  3. [LSI] Ідентифікатор клієнта з умовним фільтром на LastPurchase

1
якщо Первинний ключ: CustomerId + AccountType (я розумію, що CustomerID є ключем розділу, а AccountType є ключем сортування) Я думаю, що Ви можете запустити операцію Запиту лише CustomerID або CustomerID + AccountType. Якщо шукати лише за AccountType, це буде сканування
Аділ,

1
Дякую @Adil. Ви праві, я відредагував свою відповідь, щоб відобразити це.
Кінман,


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.


Чи можете ви вказати джерело своєї відповіді?
AlikElzin-kilaka


10

Запит набагато кращий, ніж сканування - з точки зору ефективності. скан, як випливає з назви, сканує всю таблицю. Але ви повинні добре знати ключ таблиці, ключ сортування, індекси та пов'язані індекси сортування, щоб знати, що ви можете використовувати Запит. якщо ви фільтруєте свій запит, використовуючи:

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

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

ви НЕ можете запитувати, якщо:

  • більше 2-х полів у фільтрі (наприклад, ключ, сортування та індексування)
  • лише ключ сортування (первинного ключа або індексу)
  • регулярні поля (не ключ, індекс або сортування)
  • змішаний індекс та сортування (індекс1 із сортом індексу2) \
  • ...

гарне пояснення: 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для найгіршого випадку.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.