Оптимизация схемы таблицы: модели таблиц, столбцы бакетирования, столбцы Key и настройка типов полей
Проектирование схемы таблицы играет важную роль в настройке производительности Doris. Оно напрямую влияет на распределение данных, параллелизм запросов и эффективность сортировки.
Неудачная схема часто приводит к следующим проблемам:
- Перекос данных, который мешает полностью использовать параллелизм запросов
- Неэффективное использование сортировки, замедляющее запросы с условиями равенства и диапазонными условиями
- Неподходящие типы полей, увеличивающие вычислительные затраты
Подробные принципы проектирования приведены в главе Проектирование таблиц. В этой главе на практических примерах рассматриваются типичные проблемы проектирования схем и рекомендации по их оптимизации.
Контрольный список для оптимизации
При проектировании схемы таблицы или поиске проблем последовательно проверьте следующее:
- Соответствует ли выбранная модель таблицы вашим задачам (Duplicate / Unique / Aggregate)?
- Обеспечивают ли столбцы бакетирования равномерное хеширование без перекоса из-за null или постоянных значений?
- Определены ли столбцы, часто используемые в запросах с условиями равенства и диапазонными условиями, как столбцы Key?
- Соответствуют ли типы полей принципу «приоритет фиксированной длине и низкой точности»?
Сценарий 1: выбор модели таблицы
Doris предоставляет три модели таблиц: Duplicate, Unique (MOR/MOW) и Aggregate. Они различаются производительностью запросов и функциональными возможностями.
Сравнение трёх моделей таблиц
| Модель таблицы | Производительность запросов | Поддержка обновлений | Типичные сценарии |
|---|---|---|---|
| Duplicate | Наивысшая | Нет | Высокопроизводительные запросы к журналам и детальным данным |
| Unique (MOW) | Высокая | Да | Дедупликация по первичному ключу при высоких требованиях к производительности запросов |
| Unique (MOR) | Средняя | Да | Дедупликация по первичному ключу при частой записи данных |
| Aggregate | Средняя | Обновление с агрегацией | Предварительно агрегированные отчёты и свёртки метрик |
Рейтинг производительности: Duplicate > MOW > MOR ≈ Aggregate
Если обновление данных не требуется, а производительность запросов должна быть высокой, отдавайте предпочтение таблице Duplicate.
Сценарий 2: выбор столбцов бакетирования
Определение в одном предложении: столбец бакетирования определяет, как данные распределяются по бакетам. Неудачный выбор приводит к перекосу данных, который становится узким местом для производительности запросов.
Грамотный выбор столбцов бакетирования позволяет:
- Предотвратить перекос данных и полностью использовать параллелизм
- Максимально использовать возможности Colocate Join и Bucket Shuffle Join
Неудачный пример: столбец c2 содержит много значений null
В следующем примере столбцом бакетирования выбран c2, но в загруженных данных c2 содержит только null. В результате все данные попадают лишь в 1 из 64 бакетов:
CREATE TABLE `t1` (
`c1` INT NULL,
`c2` INT NULL
) ENGINE=OLAP
DUPLICATE KEY(`c1`)
DISTRIBUTED BY HASH(`c2`) BUCKETS 64
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
insert into t1 select number, null from numbers ('number'='10000000');
Оптимизация: переход на столбец с высокой кардинальностью
Замените столбец бакетирования c2 на c1, чтобы равномерно распределить данные по бакетам и повысить эффективность параллельной обработки.
Команда для диагностики перекоса данных
Назначение: проверить, есть ли перекос данных в столбце бакетирования. Команда:
select c2, count(*) cnt from t1 group by c2 order by cnt desc limit 10;
Пояснение: если cnt для наиболее частых значений значительно больше, чем для остальных, в столбце наблюдается сильный перекос и он не подходит для бакетирования.
Принципы выбора столбцов бакетирования
- Избегайте столбцов, которые в ваших данных часто содержат null или постоянные значения
- Предпочитайте поля с высокой кардинальностью, например идентификатор пользователя или заказа
- Оценивайте распределение значений поля до создания таблицы и при необходимости проверяйте его на выборке
Проверьте, есть ли перекос данных в столбце бакетирования. Если есть, замените его полем с более высокой кардинальностью. Продуманное проектирование существенно снижает затраты на последующую диагностику и исправление проблем.
Сценарий 3: оптимизация столбцов Key
Определение в одном предложении: Doris сортирует данные по столбцам Key на уровне хранения. Если определить часто запрашиваемые столбцы как столбцы Key, можно значительно ускорить запросы с условиями равенства и диапазонными условиями.
Примеры рабочих запросов
select * from t1 where t1.c1 = 1;
select * from t1 where t1.c1 > 1 and t1.c1 < 10;
select * from t1 where t1.c1 in (1, 2, 3);
Оптимизация: определение c1 как столбца Key
CREATE TABLE `t1` (
`c1` INT NULL,
`c2` INT NULL
) ENGINE=OLAP
DUPLICATE KEY(`c1`)
DISTRIBUTED BY HASH(`c2`) BUCKETS 10
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
Определяйте столбцы, часто используемые в рабочих запросах с условиями равенства или диапазонными условиями, как столбцы Key, чтобы ускорить обработку запросов.
Сценарий 4: оптимизация типов полей
Определение в одном предложении: типы полей напрямую влияют на вычислительную сложность. Типы фиксированной длины и низкой точности обрабатываются эффективнее, чем типы переменной длины и высокой точности.
Принципы выбора типов
| Принцип | Рекомендуется | Следует избегать |
|---|---|---|
| Приоритет фиксированной длине | INT, BIGINT, DATE, DATETIME | VARCHAR, STRING |
| Приоритет низкой точности | INT, BIGINT, FLOAT | DECIMAL (в сценариях с высокой точностью) |
Типичные сценарии замены
- Заменяйте поля VARCHAR / STRING, используемые для хранения числовых значений, на BIGINT
- Заменяйте поля DECIMAL на FLOAT / INT / BIGINT, если точность DECIMAL не требуется
- Заменяйте строковые поля для хранения времени на DATETIME
При выборе типов полей схемы следуйте принципу «приоритет фиксированной длине и низкой точности», чтобы повысить эффективность вычислений и производительность системы.
Часто задаваемые вопросы
Вопрос 1: что делать, если после создания таблицы выяснилось, что столбец бакетирования выбран неудачно?
После создания таблицы столбец бакетирования нельзя изменить напрямую. Нужно создать новую таблицу и повторно загрузить данные либо с помощью ALTER TABLE создать новый Rollup или схему партиционирования. Рекомендуется тщательно оценивать кардинальность полей до создания таблицы.
Вопрос 2: всегда ли большее количество столбцов Key лучше?
Нет. Избыточное количество столбцов Key увеличивает затраты на сортировку при хранении и на запись данных. Определяйте как столбцы Key только те столбцы, которые действительно часто используются для фильтрации по равенству или диапазону.
Вопрос 3: когда необходимо использовать модель Unique или Aggregate?
- Если нужна дедупликация или обновление данных по первичному ключу, используйте Unique
- Если нужна предварительная агрегация (SUM, MAX, MIN и т. д.), используйте Aggregate
- Для детальных данных, которые только добавляются, при предельно высоких требованиях к производительности запросов используйте Duplicate
Вопрос 4: как определить, есть ли перекос данных в текущей таблице?
Выполните следующий SQL-запрос, чтобы проверить распределение значений столбца бакетирования:
select <bucket_col>, count(*) cnt from <table> group by <bucket_col> order by cnt desc limit 10;
Если количество строк для наиболее частых значений намного превышает количество строк для остальных, перекос есть.
Итоги
Тщательно спроектированная схема позволяет максимально использовать возможности Doris и значительно повысить производительность запросов. Неудачная схема может вызывать проблемы во всей системе, например перекос данных.
Основные направления оптимизации:
- Предпочитайте модель таблицы Duplicate, если обновление данных не требуется
- Выбирайте столбцы бакетирования с высокой кардинальностью, избегая null и постоянных значений
- Определяйте часто запрашиваемые столбцы как столбцы Key
- При выборе типов полей следуйте принципу «приоритет фиксированной длине и низкой точности»
Продуманное проектирование всегда обходится дешевле последующей оптимизации. Рекомендуется строго соблюдать приведённые принципы на этапе проектирования схемы.