предложение 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.