Кассандра выбрать с помощью ключа кластеризации

У меня проблема с Кассандрой ( ScyllaDB (индексы не поддерживаются!))

в моем сценарии у меня есть таблица с тремя столбцами

CREATE TABLE test (a text , b text , c text , PRIMARY KEY ( a , b ,c ) );

Теперь я хочу выбрать данные по второму ключу кластера ( c), но необходим b.

Моя цель, но неверный запрос:

SELECT * FROM test WHERE c='...' ALLOW FILTERING

И правильный запрос таков:

SELECT * FROM test WHERE b='...' AND c='...' ALLOW FILTERING

Есть ли решение для моей проблемы, чтобы использовать только ключ кластера b в запросе выбора?

3 ответа

Решение

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

Прежде всего, ALLOW FILTERING предложение уже ставит ударение на все узлы Cassandra в кластере. Поскольку в запросе не указан ключ раздела, каждый из узлов должен будет обработать его, загрузив данные с диска и отбросив записи, которые не соответствуют предоставленным критериям. Но, насколько я понимаю, из-за того, что Cassandra хранит данные в файлах, она может загружать только свое подмножество на основе ключа кластеризации, предоставленного в запросе. Однако, только если либо указаны все компоненты ключа кластеризации, либо пропущен только один или несколько из последних.

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

Этот пост объясняет более подробно влияние ALLOW FILTERING в то время как этот погружается глубже в SQL WHERE пункт в общем.

Возможное решение

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

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

Вы можете запросить на

  • SELECT * FROM test WHERE a='...'
  • а и б SELECT * FROM test WHERE a='...' AND b='...'
  • а и б и в SELECT * FROM test WHERE a='...' AND b='...' AND c='...'

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

Косметика: в CREATE TABLE () вокруг a не нужны, так как вы не применяете составной ключ раздела:

CREATE TABLE test (a text, b text, c text, PRIMARY KEY (a, b, c))

В общем, Сцилла стремится достичь паритета характеристик с Кассандрой. С этой целью ограничения Сциллы в отношении фильтрации ключей кластера такие же, как и у Кассандры (применяются другие комментарии в этой теме). Scylla 2.0 RC1 будет выпущен в ближайшее время с экспериментальной версией материализованных представлений. Вы можете прочитать о том, что будет и не будет поддерживаться в версии 2.0 RC1 здесь: http://www.scylladb.com/2017/07/27/materialized-views-preview-scylla-2-0/.

Другие вопросы по тегам