Дан пример следующего выбора в CQL:

SELECT * FROM tickets WHERE ID IN (1,2,3,4)

Данный идентификатор является ключом раздела, лучше ли использовать отношение IN, чем выполнение нескольких запросов, или нет никакой разницы?

13
Andy Leung 18 Ноя 2014 в 19:25

2 ответа

Лучший ответ

Я вспомнил, как некоторое время назад кто-то отвечал на этот вопрос в списке рассылки пользователей Cassandra, но я не могу найти точное сообщение прямо сейчас. По иронии судьбы, евангелист Кассандры Ребекка Миллс только что опубликовала статью, в которой рассматривается эта проблема (Что нужно делать при использовании драйверов Cassandra < /a>... точки 13 и 22). Но ответ - «да», что в некоторых случаях несколько параллельных запросов будут быстрее, чем использование IN. Основная причина может быть найдена в документации DataStax SELECT.

Когда не использовать IN

... Использование IN может снизить производительность, потому что обычно нужно опрашивать многие узлы. Например, в одном кластере локального центра обработки данных с 30 узлами, коэффициентом репликации 3 и уровнем согласованности LOCAL_QUORUM один ключевой запрос отправляется на два узла, но если запрос использует условие IN, количество запрашиваемые узлы, скорее всего, даже выше, до 20 узлов в зависимости от того, где ключи попадают в диапазон токенов.

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

Следовательно, лучший способ решить эту проблему (и вообще не использовать IN) - это переосмыслить вашу модель данных для этого запроса. Не зная слишком много о вашей схеме, возможно, есть атрибуты (значения столбцов), которые являются общими для идентификаторов билетов 1, 2, 3 и 4. Может быть, используя что-то вроде уровня или группы (если билеты предназначены для определенного места проведения) или, может быть, даже вместо этого событие (id).

По сути, хотя использование уникального идентификатора с высокой мощностью для разделения ваших данных звучит как хорошая идея, на самом деле это затрудняет последующий запрос ваших данных (в Cassandra). Если бы вы могли придумать другой столбец для разделения данных, это, безусловно, помогло бы вам в этом случае. В любом случае создание нового, определенного семейства столбцов (таблицы) для обработки запросов для этих строк будет лучшим подходом, чем использование IN или нескольких запросов.

24
Aaron 19 Ноя 2014 в 05:50
Как насчет запроса delete? В настоящее время у меня есть запрос DELETE FROM xyz WHERE pkey IN(1,2,3,4). Является ли оператор IN для DELETE лучше, чем SELECT?
 – 
pinkpanther
19 Фев 2015 в 21:35
1
Это зависит от того, заботитесь ли вы о том, чтобы эта операция удаления выполнялась хорошо. Если у вас несколько узлов, я думаю, что у вас возникнут те же проблемы с производительностью. Но если вы просто выполняете одноразовое техническое удаление, я бы не стал об этом беспокоиться.
 – 
Aaron
19 Фев 2015 в 21:42
1
Рекомендация консолидировать записи под ключом секции с более высокой кардинальностью хороша для оптимизации запроса IN, однако вы должны помнить о размере секции. Оптимальный размер составляет около 100 МБ, поэтому, если ваши разделы станут намного больше этого размера, вам следует подумать о другом способе их разделения. Поскольку модель данных является самым важным фактором, определяющим производительность Cassandra, я предлагаю использовать данные курс моделирования от Академии DataStax.
 – 
Andrew Weaver
21 Июл 2016 в 16:02
1
Если вы предоставляете ключ секции и используете IN для ключа кластеризации, вы сможете извлечь данные, обратившись только к одному узлу. Однако вы все равно заставите Cassandra читать случайным образом (а не последовательно) внутри раздела. Производительность такого запроса во многом будет зависеть от размера раздела и количества ключей кластеризации.
 – 
Aaron
14 Апр 2020 в 18:58
1
Хорошо, понял, «вы все равно заставите Кассандру читать случайным образом (а не последовательно) внутри раздела», это хорошо, спасибо
 – 
User3518958
14 Апр 2020 в 19:38

Да, лучше запрашивать индивидуально, чем использовать IN в Cassandra.

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

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

2
Nandakishore 1 Апр 2016 в 09:33