Перейти к содержимому
Последнее обновление

Построчное хранение

Row Store — это возможность Doris, которая дополняет колоночное хранение компактной двоичной копией каждой строки в построчном формате. При точечных запросах она позволяет заменить «одну операцию IO на каждый столбец» на «одну операцию IO для чтения всей строки». Эта возможность поддерживается начиная с Doris 2.0.0.

По умолчанию Doris использует колоночное хранение, при котором данные каждого столбца хранятся непрерывно. Колоночное хранение хорошо подходит для аналитических сценариев (агрегации, фильтрации, сортировки и так далее), поскольку позволяет читать только необходимые столбцы. Однако при точечных запросах (например, SELECT *) требуется прочитать все столбцы, выполнив по одной операции IO для каждого из них. В широких таблицах с большим количеством столбцов (например, сотнями) IOPS становится узким местом.

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

Сценарии применения​

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

СценарийТипичный шаблон запросаТребования к модели таблицыРекомендация
Точечные запросы по первичному ключу с высокой конкурентностьюSELECT ... FROM t WHERE pk1 = ? AND pk2 = ?Таблица Unique Key MOWРекомендуется
TOPN-запросы к широким таблицамSELECT * FROM t [WHERE ...] ORDER BY ... LIMIT NТаблица Duplicate / таблица Unique Key MOWРекомендуется
Аналитические запросыАгрегация, сложная фильтрация по небольшому числу столбцов и так далее—Не рекомендуется (достаточно колоночного хранения)

В следующих разделах описаны условия активации, способы создания таблиц и примеры запросов для каждого сценария.

Сценарий 1: точечные запросы по первичному ключу с высокой конкурентностью​

Этот сценарий подходит для запросов с высокой конкурентностью к таблицам Unique Key MOW, в которых поиск конкретных строк выполняется по полному первичному ключу. При соблюдении условий запрос выполняется по пути Short-Circuit, минуя стандартный конвейер выполнения.

Условия активации​

Все следующие условия должны выполняться одновременно:

  1. Таблица использует модель Unique Key MOW ("enable_unique_key_merge_on_write" = "true").
  2. Построчное хранение включено с помощью "store_row_column" = "true" или "row_store_columns" = "...".
  3. Предложение WHERE содержит условия равенства для всех столбцов первичного ключа, соединённые оператором AND.

Пример создания таблицы​

В следующем примере создаётся таблица с 8 столбцами, построчное хранение включается только для 5 из них, а параметру page_size задаётся значение 4 KB для достижения наилучшей производительности точечных запросов:

CREATE TABLE `tbl_point_query` (
`k` int(11) NULL,
`v1` decimal(27, 9) NULL,
`v2` varchar(30) NULL,
`v3` varchar(30) NULL,
`v4` date NULL,
`v5` datetime NULL,
`v6` float NULL,
`v7` datev2 NULL
) ENGINE=OLAP
UNIQUE KEY(`k`)
COMMENT 'OLAP'
DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"light_schema_change" = "true",
"row_store_columns" = "k,v1,v3,v5,v7",
"row_store_page_size" = "4096"
);

Пример запроса​

-- Query all columns
SELECT * FROM tbl_point_query WHERE k = 100;

-- Query a subset of columns
SELECT k, v1, v3, v5, v7 FROM tbl_point_query WHERE k = 100;

Построчное хранение части столбцов: если построчно хранится только часть столбцов (например, v1), а запрос обращается к столбцу, который не хранится построчно (например, v2), Doris читает недостающий столбец из колоночного хранилища. Столбцы, хранящиеся построчно, по-прежнему читаются эффективно, а для остальных выполняются обычные операции IO колоночного хранения.

Способ проверки​

Выполните EXPLAIN для запроса. В выводе должен присутствовать маркер SHORT-CIRCUIT. Подробнее см. в разделе Точечные запросы с высокой конкурентностью.

Сценарий 2: TOPN-запросы с отложенной материализацией​

Этот сценарий подходит для запросов SELECT * к широким таблицам Duplicate или Unique Key MOW, которые «сортируют данные, а затем выбирают небольшое количество строк». При соблюдении условий запрос выполняется по пути Fetch Row Store и в сочетании с двухфазной оптимизацией TOPN извлекает только строки, фактически попавшие в результат.

Условия активации​

Все следующие условия должны выполняться одновременно:

  1. Таблица использует модель Duplicate или Unique Key MOW ("enable_unique_key_merge_on_write" = "true").
  2. Построчное хранение должно быть включено для всех столбцов ("store_row_column" = "true").
  3. Запрос соответствует шаблону SELECT * FROM tbl [WHERE ...] ORDER BY ... LIMIT N.
  4. Запрос должен использовать SELECT *; выбор отдельных столбцов не поддерживается.
  5. Должна сработать оптимизация отложенной материализации TOPN. Подробнее см. в разделе Оптимизация TOPN-запросов.

Пример создания таблицы​

CREATE TABLE `tbl_duplicate` (
`k` int(11) NULL,
`v1` string NULL
) ENGINE=OLAP
DUPLICATE KEY(`k`)
COMMENT 'OLAP'
DISTRIBUTED BY HASH(`k`) BUCKETS 1
PROPERTIES (
"light_schema_change" = "true",
"store_row_column" = "true",
"row_store_page_size" = "4096"
);
примечание

Для таблиц Duplicate необходимо задать "store_row_column" = "true"; указание части столбцов через row_store_columns не поддерживается. Все столбцы хранятся построчно.

Пример запроса​

SELECT * FROM tbl_duplicate WHERE k < 10 ORDER BY k LIMIT 10;

Способ проверки​

Выполните EXPLAIN для запроса. В выводе должны присутствовать оба маркера: FETCH ROW STORE и OPT TWO PHASE.

Параметры конфигурации​

Задайте следующие параметры в PROPERTIES при выполнении CREATE TABLE:

ПараметрЗначение по умолчаниюПоддерживаемые версииОписание
store_row_columnfalse2.0+При значении true включает построчное хранение для всех столбцов.
row_store_columnsВсе столбцы3.0+Включает построчное хранение только для указанных столбцов, перечисленных в формате "col1,col2,...". При задании этого параметра неявно включается store_row_column. По сравнению с построчным хранением всех столбцов это позволяет существенно снизить дополнительные затраты на хранение.
row_store_page_size16384 (16 KB)2.0+Размер страницы построчного хранения в байтах. Страница — минимальная единица IO: даже чтение одной строки требует операции IO объёмом в одну страницу.

Рекомендации по настройке row_store_page_size​

row_store_page_size напрямую влияет на соотношение между производительностью точечных запросов и дополнительными затратами на хранение:

Цель оптимизацииРекомендуемое значениеКомпромисс
Наилучшая производительность точечных запросов4096 (4 KB) или меньшеБолее высокие дополнительные затраты на хранение
Сбалансированный вариант (по умолчанию)16384 (16 KB)—
Минимальные дополнительные затраты на хранение65536 (64 KB) или большеБолее высокая задержка точечных запросов

Примечания​

  1. Дополнительные затраты на хранение: включение построчного хранения увеличивает использование дискового пространства. В зависимости от характеристик данных объём дополнительного хранения обычно составляет от 2 до 10 исходных размеров таблицы. Проверьте влияние на реальных данных.
  2. Влияние page_size на объём хранения: меньшее значение row_store_page_size повышает производительность точечных запросов, но увеличивает дополнительные затраты на хранение. Рекомендации по настройке приведены в разделе Параметры конфигурации.
  3. ALTER не поддерживается: изменение свойств store_row_column и row_store_columns с помощью ALTER TABLE не поддерживается.