21

Я не уверен, насколько лучше, по эффективности использовать широко распространенное значение столбца (например, Country) в качестве ключа раздела для составного первичного ключа или довольно уникального значения столбца (например, Last_Name).Cassandra: выбирая ключ раздела

Глядя на Cassandra 1.2's documentation about indexes я получаю это:

"Когда использовать индекс:. Кассандр встроенных индексов лучше всего на столе , имеющие много строк, которые содержат индексированное значение Чем больше уникальные значения , которые существуют в конкретном столбце, тем больше накладных расходов вы должны в среднем запросить и поддерживать индекс. Например, предположим, что у вас была пользовательская таблица с миллиардом пользователей и хотела посмотреть до пользователей, в которых они проживали. Многие пользователи будут иметь одинаковое значение столбца для состояния (например, CA, NY, TX и т. Д.). Это будет хорошим кандидатом на индекс. «

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

Looking at the examples from CQL's SELECT для

«Запрашивания составных первичных ключей и сортировки результатов», я вижу что-то вроде UUID используется в качестве ключа секционирования ... который будет означать, что предпочтительнее использовать что-то довольно уникальное?

enter image description here

ответ

39

Индексирование в документации, которую вы написали, относится к вторичным индексам. В кассандре есть difference between the primary and secondary indexes. Для вторичного индекса было бы действительно иметь очень уникальные значения, однако для компонентов в первичном ключе это зависит от того, на каком компоненте мы фокусируемся. В первичном ключе мы имеем следующие компоненты:

PRIMARY KEY (ключ секционирования, кластеризация Key_1 ... кластеризация Key_N)

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

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

cql docs имеют хорошее объяснение того, что происходит.

+0

Означает ли это, что «ключ разделения» - это одна строка, а «кластеризация key_1» и т. Д., Упорядочивает ли значение внутри одной строки? Спасибо за ваш ответ, это ответ, который я приземлился после долгого поиска корреляции между Partitioner, Partition Key и Compound Primary Key. Из того, что я вижу, это ключ раздела, который испортил распределение между кластером, и если это случайный случай, остальная часть составного ключа, то есть кластеризация key_1 и т. Д., КЛАВИАТУРНЫЕ КЛАВИШИ НЕ ВЛИЯЮТ РАСПРОСТРАНЕНИЕ ИЗ УДОВЛЕТВОРЕНИЙ , –

+2

@RavindranathAkila Кластерный ключ влияет на выравнивание столбцов (упорядоченных) в физическом узле, но вы правы, что распределение между узлами зависит исключительно от ключа секционирования. –

+0

Спасибо, Любен! Это очень помогает! –

8

если вы используете cql3, данный столбец семьи:

CREATE TABLE table1 (
    a1 text, 
    a2 text, 
    b1 text, 
    b2 text, 
    c1 text, 
    c2 text, 
    PRIMARY KEY ((a1, a2), b1, b2)) 
); 

путем определения первичного ключа ((a1, a2, ...), b1, b2, ...)

Это означает, что:

a1, a2, ... являются поля используются для изготовления ключа строки для того, чтобы:

  • определяют как данные разбиения
  • определить, что хранится в Специальных условиях одной строки
  • называют рядом ключ или раздел ключа

b1, b2, ... столбцами семейства полей, используемое для кластеризации ключа строки для того, чтобы:

  • создавать логические наборы внутри одной строки
  • позволяют более гибкие схемы поиска, такие как диапазон диапазона
  • называют как ключ столбца или CLUS ter

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

Если вы хотите использовать запросы диапазона, вы можете использовать вторичные индексы или (начиная с cql3), вы можете объявить эти поля как ключи кластеризации. С точки зрения скорости их использования в качестве ключа кластеризации будет создан один широкий ряд. Это оказывает влияние на скорости, так как вы будете получать множественную кластеризацию ключевых ценностей, такие как:

select * from accounts where Country>'Italy' and Country<'Spain'

+0

Мне интересно о производительности при использовании ключей кластеризации и запросов диапазона. Документация довольно вокальная, только с использованием вторичных индексов для сравнений сравнений сравнений сравнений сравнений (из-за индексации KEYS) будет проведена Cassandra. Как запросы диапазона с ключами кластеризации (т. Е. Части первичного ключа не составляют ключ строки/раздела), знаете ли вы? – DanielSmedegaardBuus

+2

Вторичные индексы эффективно создают двоичное дерево ключей хэш-строк, разделенных выбранным столбцом. Хотя ключи столбца предназначены для индексирования столбцов в строке. Вторичные индексы должны использоваться только в том случае, если мощность значений столбца низкая (например, страны или почтовые индексы) – natbusa

+0

ПЕРВИЧНЫЙ КЛЮЧ ((a1), b1, b2)) является таким же, как ключи PRIMARY KEY (a1, b1, b2) – natbusa

1

Я уверен, что вы получили бы ответ, но все же это может помочь вам для лучшего понимания.

CREATE TABLE table1 (
    a1 text, 
    a2 text, 
    b1 text, 
    b2 text, 
    c1 text, 
    c2 text, 
    PRIMARY KEY ((a1, a2), b1, b2)) 
); 

здесь ключи раздела (a1, a2), а строки - b1, b2.

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

вышеуказанный первичный ключ можно определить следующим образом.

Node< key, value> 

Node<(a1a2), Map< b1b2, otherColumnValues>> 

как мы знаем Partition Key отвечает за распределение данных accross ваших узлов.

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

логически мы можем представлять как это.

Node<(a1a2), Map< string1, otherColumnValues>, Map< string2, otherColumnValues> .... Map< string100, otherColumnValues>> 

Таким образом, запись будет храниться последовательно в памяти.

 Смежные вопросы

  • Нет связанных вопросов^_^