предложение order by не работает в запросе Cassandra
Я создал слой таблицы, используя следующий код:
CREATE TABLE layer (
layer_name text,
layer_position text,
PRIMARY KEY (layer_name, layer_position)
) WITH CLUSTERING ORDER BY (layer_position DESC)
Я использую приведенный ниже запрос для извлечения данных из таблицы слоев в порядке убывания (слой):
$select = new CassandraSimpleStatement(<<<EOD
select * from layer ORDER BY layer_position DESC
EOD
);
$result = $session->execute($select);
но этот запрос не работает. Пожалуйста, кто-нибудь может мне помочь?
2 ответов
проще говоря, Кассандра только обеспечивает порядок сортировки внутри ключ раздела.
PRIMARY KEY (layer_name, layer_position)
) WITH CLUSTERING ORDER BY (layer_position DESC)
в этом случае layer_name
- это ваш ключ раздела. Если указать layer_name
в вашем предложении WHERE ваши результаты для этого значения layer_name
будет заказан layer_position
.
SELECT * FROM layer WHERE layer_name = 'layer1';
вам не нужно указывать ORDER BY. Все, что действительно можно сделать на уровне запроса, - это применить другое направление сортировки (по возрастанию и убыванию).
Кассандра работает таким образом, потому что он предназначен для чтения данных в любом порядке, он сортируется на диске. Ключи разделов сортируются по хэшированному значению токена, поэтому в предложении unbound WHERE порядок упорядочивается случайным образом.
редактировать
я должен получить данные, используя
state_id
столбец, и он должен быть упорядочен поlayer_position
.
таблицы Cassandra оптимизированы для конкретного запроса. А это приводит к высокой производительность, недостатком является то, что гибкость запроса ограничена. Способ решения этой проблемы-дублировать данные в дополнительную таблицу, предназначенную для обслуживания этого конкретного запроса.
CREATE TABLE layer_by_state_id (
layer_name text,
layer_position text,
state_id text,
PRIMARY KEY (state_id, layer_position, layer_name)
) WITH CLUSTERING ORDER BY (layer_position DESC, layer_name ASC);
эта таблица позволит таким запросам работать:
SELECT * FROM layer WHERE state_id='thx1138';
и результаты будут отсортированы по layer_position
, в пределах запрашиваемого state_id
.
теперь я делаю несколько предположений, которые вы захотите исследовать:
- я предполагая, что
state_id
является хорошим ключом разбиения. Это означает, что он имеет достаточно высокую мощность, чтобы обеспечить хорошее распределение в кластере, но достаточно низкую мощность, чтобы вернуть достаточно строк CQL, чтобы сделать сортировку стоящей. - я предполагаю, что комбинация
state_id
иlayer_position
is не достаточно, чтобы однозначно идентифицировать каждую строку. Поэтому я гарантирую уникальность, добавивlayer_name
как дополнительный ключ кластеризации. Тебе это может понадобиться, а может и нет, но я ... полагаю, что так и будет. - я предполагаю, что с помощью
state_id
как ключ разбиения не будет демонстрировать несвязанный рост, чтобы приблизиться к пределу Кассандры в 2 миллиарда клеток на раздел. Если это так, вам может потребоваться добавить дополнительный раздел "ведро"."
вы не можете использовать order by
непосредственно в Афинах.
вы можете применить order by
на столбцах кластеризации только тогда, когда ваш ключ раздела будет ограничен EQ
или IN
.