forked from ydb-platform/ydb
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
YDBDOCS-740: update dev/primary-key/column-oriented.md (ydb-platform#…
- Loading branch information
Showing
2 changed files
with
16 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,17 @@ | ||
# Selecting a primary key for maximum column-oriented table performance | ||
# Choosing keys for maximum column-oriented table performance | ||
|
||
Unlike row-oriented {{ ydb-short-name }} tables, you can't partition column-oriented tables by primary keys but only by specially designated partitioning keys. Inside each partition, data is distributed by the table's primary key. | ||
Unlike row-oriented {{ ydb-short-name }} tables, column-oriented tables are partitioned by designated **partitioning keys**. Within each partition, data is distributed based on the table's primary key. | ||
|
||
In this context, to ensure high performance of column-oriented {{ ydb-short-name }} tables, you need to properly select both the primary key and partitioning key. | ||
## Partitioning key | ||
|
||
Because the partitioning key determines the partition where the data is stored, select it so that the Hash(partition_key) enables uniform distribution of data across partitions. The optimal situation is when the partitioning key includes 100 to 1,000 times more unique values than the number of partitions in the table. | ||
The partitioning key must be a non-empty subset of the primary key columns. The hash of the partition key determines the partition to which the row belongs. The partition key should be chosen to ensure that data is evenly distributed across partitions. This is typically achieved by including high-cardinality columns, such as high-resolution timestamps (`Timestamp` data type), in the partition key. Using a partitioning key with low cardinality can lead to an uneven distribution of data across partitions, causing some partitions to become overloaded. Overloaded partitions may result in suboptimal query performance and/or limit the maximum rate of data insertion. | ||
|
||
Keys with many unique values have high cardinality. On the other hand, keys with a few unique values have low cardinality. Using a partitioning key with low cardinality might result in uneven distribution of data across partitions, and some partitions might become overloaded. Overloading of partitions might result in suboptimal query performance and/or capping of the maximum stream of inserted data. | ||
|
||
The primary key determines how the data will be stored inside the partition. That's why, when selecting a primary key, you need to keep in mind both the effectiveness of reading data from the partition and the effectiveness of inserting data into the partition. The optimum insert use case is to write data to the beginning or end of the table, making rare local updates of previously inserted data. For example, an effective use case would be to store application logs by timestamps, adding records to the end of the partition using the current time in the primary key. | ||
|
||
{% note warning %} | ||
|
||
Currently, you need to select the primary key so that the first column in the primary key has high cardinality. An example of an effective first column is the column with the `Timestamp` type. For example, the first column is ineffective if it has the `Uint16` type and 1,000 unique values. | ||
Column-oriented tables do not support automatic repartitioning at the moment. That's why it's important to specify a realistic number of partitions at table creation. You can evaluate the number of partitions you need based on the expected data amounts you are going to add to the table. The average insert throughput for a partition is 1 MB/s. The throughput is mostly affected by the selected primary keys (the need to sort data inside the partition when inserting data). We do not recommend setting up more than 128 partitions for small data streams. | ||
|
||
{% endnote %} | ||
## Primary key | ||
|
||
Column-oriented tables do not support automatic repartitioning at the moment. That's why it's important to specify a realistic number of partitions at table creation. You can evaluate the number of partitions you need based on the expected data amounts you are going to add to the table. The average insert throughput for a partition is 1 MB/s. The throughput is mostly affected by the selected primary keys (the need to sort data inside the partition when inserting data). We do not recommend setting up more than 128 partitions for small data streams. | ||
The primary key determines how the data will be stored inside the partition. That's why, when selecting a primary key, you need to keep in mind both the effectiveness of reading data from the partition and the effectiveness of inserting data into the partition. The optimum insert use case is to write data to the beginning or end of the table, making rare local updates of previously inserted data. For example, an effective use case would be to store application logs by timestamps, adding records to the end of the partition using the current time in the primary key. | ||
|
||
Example: | ||
## Example | ||
|
||
When your data stream is 1 GB per second, an analytical table with 1,000 partitions is an optimal choice. Nevertheless, it is not advisable to create tables with an excessive number of partitions: this could raise resource consumption in the cluster and negatively impact the query rate. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,17 @@ | ||
# Выбор первичного ключа для максимальной производительности колоночных таблиц | ||
# Выбор ключей для максимальной производительности колоночных таблиц | ||
|
||
В отличие от строковых таблиц {{ ydb-short-name }}, колоночные таблицы партиционируют данные не по первичным ключам, а по специально выделенным ключам — ключам партицирования. При этом внутри каждой партиции данные распределяются в порядке первичного ключа таблицы. | ||
В отличие от строковых таблиц {{ ydb-short-name }}, колоночные таблицы партиционируют данные не по первичным ключам, а по специально выделенным ключам — **ключам партицирования**. При этом внутри каждой партиции данные распределяются в порядке первичного ключа таблицы. | ||
|
||
Поэтому для эффективной работы с колоночными таблицами {{ ydb-short-name }} необходимо правильно выбирать первичный ключ и ключ партицирования. | ||
## Ключ партиционирования | ||
|
||
Так как ключ партицирования определяет партицию, в которой хранятся данных, то его следует выбирать так, чтобы Hash(partition_key) приводил к равномерному распределению данных по партициям. Оптимально, если ключ партицирования содержит в 100-1000 раз больше уникальных значений, чем число партиций в таблице. | ||
Ключ партиционирования должен являться непустым подмножеством столбцов первичного ключа. Хэш от ключа партиционирования определяет партицию, в которую попадёт строка. Ключ следует выбирать таким образом, чтобы данные распределялись равномерно по партициям. Обычно этого достигают путём включения в ключ партиционирования высококардинальных столбцов, например, временных меток с высоким разрешением (тип данных `Timestamp`). Если в качестве ключа партиционирования используется низкокардинальный ключ, данные могут распределиться по партициям неравномерно, что приведёт к перегрузке некоторых партиций. Перегрузка партиций вызывает неоптимальную производительность запросов и/или накладывает ограничения на максимальный поток вставляемых данных. | ||
|
||
Ключи, у которых существует большое количество уникальных значений, называются высококардинальными, и, наоборот, если уникальных значений мало, то такие ключи называются низкокардинальными. Если в качестве ключа партицирования используется низкокардинальный ключ, данные могут распределиться по партициями неравномерно, перегрузив часть партиций. Перегрузка партиций приведет к неоптимальной производительности запросов и/или ограничениям на максимальный поток вставляемых данных. | ||
|
||
Первичный ключ определяет порядок хранения данных внутри партиции, поэтому при выборе первичного ключа необходимо учитывать не только эффективность сценария чтения данных из партиции, но и эффективность вставки данных в партицию. Оптимальный сценарий вставки — запись данных в начало или в конец таблицы с редкими локальными обновлениями уже вставленных данных. Например, эффективен сценарий хранения журналов работы приложений, когда данные хранятся по временным меткам, а новые записи добавляются в конец партиции за счет использования текущего времени в первичном ключе. | ||
|
||
{% note warning %} | ||
|
||
В настоящий момент необходимо таким образом выбирать первичный ключ, чтобы в качестве первой колонки первичного ключа использовалась высококардинальная колонка. Примером эффективной первой колонки является колонка с типом `Timestamp` (временная метка). Примером неэффективной первой колонки является колонка с типом `Uint16` и 1000 уникальных значений. | ||
В настоящий момент колоночные таблицы не поддерживают автоматического репартицирования, поэтому важно указывать правильное число партиций при создании таблицы. Оценить необходимое количество партиций можно по предполагаемому объему добавляемых в таблицу данных. Средняя пропускная способность партиции на добавление данных — 1 МБ/c. При этом пропускная способность в первую очередь определяется выбранным первичным ключом (необходимостью сортировки данных внутри партиции при добавлении новых данных). Для небольших потоков данных не рекомендуется задавать больше 128 партиций. | ||
|
||
{% endnote %} | ||
## Первичный ключ | ||
|
||
В настоящий момент колоночные таблицы не поддерживают автоматического репартицирования, поэтому важно указывать правильное число партиций при создании таблицы. Оценить необходимое количество партиций можно по предполагаемому объему добавляемых в таблицу данных. Средняя пропускная способность партиции на добавление данных — 1 МБ/c. При этом пропускная способность в первую очередь определяется выбранным первичным ключом (необходимостью сортировки данных внутри партиции при добавлении новых данных). Для небольших потоков данных не рекомендуется задавать больше 128 партиций. | ||
Первичный ключ определяет порядок хранения данных внутри партиции, поэтому при выборе первичного ключа необходимо учитывать не только эффективность сценария чтения данных из партиции, но и эффективность вставки данных в партицию. Оптимальный сценарий вставки — запись данных в начало или в конец таблицы с редкими локальными обновлениями уже вставленных данных. Например, эффективен сценарий хранения журналов работы приложений, когда данные хранятся по временным меткам, а новые записи добавляются в конец партиции за счет использования текущего времени в первичном ключе. | ||
|
||
Пример: | ||
## Пример | ||
|
||
При потоке данных в 1 ГБ/с оптимально использовать аналитическую таблицу с 1000 партиций. При этом создавать таблицы со значительным запасом партиций не стоит, т.к. это приведет к росту потребляемых ресурсов в кластере и итоговому замедлению скорости выполнения запросов. |