Выделим пять важнейших аспектов работы: развертывание, моделирование данных, загрузка данных, выполнение запросов и мониторинг.
В предыдущей статье Вы познакомились с советами по развертыванию Селены. В этой статье мы рассмотрим моделирование данных.
Моделирование данных
При моделировании данных в StarRocks необходимо учесть множество факторов. В этой статье вы познакомитесь с ключевыми.
Стандарты создания таблиц
- Поддерживается только кодировка UTF-8.
- Переименование столбцов не поддерживается (но скоро будет).
- Максимальная длина VARCHAR — 1048576.
- В ключевых столбцах нельзя указывать значения FLOAT и DOUBLE.
- Имена каталогов, баз данных, таблиц, представлений, пользователей и ролей чувствительны к регистру; имена столбцов и партиций — нет.
- В таблице с первичным ключом общий размер ключевых столбцов не должен превышать 128 байт.
Как выбрать тип таблицы?
- Для хранения подробных записей (таблицы фактов) используйте таблицу с дублирующимися ключами.
- Таблица с первичным ключом подходит, если у вас есть уникальный столбец, содержащий значения, отличные от null, операции записи и чтения выполняются часто, а неключевые столбцы используют индексы.
- В таблице с уникальным ключом должен быть уникальный столбец, который может содержать значения null, при этом данные часто записываются и нечасто считываются.
- Агрегированная таблица содержит только агрегированные данные.
Подробное сравнение разных типов таблиц см. в документации к StarRocks.
Выбор столбцов сортировки и префиксных индексов
- Для версий StarRocks до 3.0 в таблице с первичным ключом столбцы сортировки указывались через PRIMARY KEY. В StarRocks 3.0 и выше столбцы сортировки в таких сценариях указываются через ORDER BY.
- Префиксные индексы — это разреженные индексы, используемые вместе со столбцами сортировками для ускорения запросов. Для оптимальной производительности префиксные индексы загружаются в память. Рекомендации по применению:
o Столбцами сортировки должны быть столбцы, часто используемые в условиях запроса. Например, если вы часто фильтруете данные по столбцу user_id, поместите его первым.
o Столбцов сортировки должно быть не больше 3–5, иначе снизится производительность при сортировке и загрузке данных.
o Префиксные индексы не должны превышать 36 байт и включать более трех столбцов. Столбцы VARCHAR в префиксных индексах обрезаются, а типы FLOAT и DOUBLE не допускаются.
При выборе ключевых столбцов и порядка полей в реальных бизнес-сценариях не забывайте о преимуществах префиксных индексов. Разместите часто запрашиваемые ключевые столбцы как можно ближе к началу и храните в этих полях даты или целочисленные значения.
Например:
CREATE TABLE site_access (
site_id BIGINT DEFAULT '10',
city_code INT,
site_name VARCHAR(50),
pv BIGINT DEFAULT '0'
)
DUPLICATE KEY(site_id, city_code, site_name)
DISTRIBUTED BY HASH(site_id);Префиксный индекс в таблице site_access: site_id (8 байт) + city_code (4 байта) + site_name (первые 24 байта).
Если условия запроса включают только столбцы site_id и city_code, как показано ниже, нужно будет просканировать гораздо меньше строк:
Если условия запроса включают только столбцы site_id и city_code, как показано ниже, нужно будет просканировать гораздо меньше строк:
select sum(pv) from site_access where site_id = 123 and city_code = 2;Если в условии запроса указан только столбец site_id, будут охвачены только строки, содержащие site_id:
select sum(pv) from site_access where site_id = 123;Если условия запроса включают только столбец city_code, нужно будет просканировать все строки, а сортировка не даст заметного преимущества:
select sum(pv) from site_access where city_code = 2;Если соотношение количества запросов к столбцам site_id и city_code вместе и запросов только к столбцу city_code примерно одинаковое, можно создать материализованное представление, чтобы упорядочить столбцы и повысить производительность запросов. В материализованном представлении мы разместим столбец city_code первым.
create materialized view site_access_city_code_mv asselect
city_code,
site_id,
site_name,
pv
from
site_access;Неэффективный пример:
CREATE TABLE site_access_bad
(
site_name VARCHAR(20),
site_id BIGINT DEFAULT '10',
city_code INT,
pv BIGINT DEFAULT '0'
)
PRIMARY KEY(site_id)
DISTRIBUTED BY HASH(site_id)
ORDER BY(site_id,city_code);В таблице site_access_bad префиксный индекс включает только site_name.
Рекомендации по партиционированию
Рекомендации по бакетированию
o Обязательно: один бакет примерно соответствует 1 ГБ, объем необработанных данных — 10 ГБ (коэффициент сжатия: 7–10 к 1). Если расчетное количество бакетов меньше числа бэкенд-узлов, фактическое количество бакетов должно равняться числу бэкенд-узлов (например, 6 узлов и 6 бакетов).
o Обязательно: на используйте динамическое бакетирование для таблиц без партиций; рассчитайте число бакетов по фактическому объему данных.
o Обязательно: избегайте динамического бакетирования, если партиции сильно различаются по размеру.
o Рекомендуется: если столбец содержит мало повторяющихся данных (например, user_id, transaction_id) и часто используется в условиях WHERE, выберите его для бакетирования.
o Рекомендуется: если запросы часто обращаются к столбцам city_id и site_id вместе, и у city_id низкая кардинальность, использование столбца city_id для бакетирования приведет к значительному перекосу. В этом случае лучше комбинировать city_id и site_id. Правда, в таком случае бакетирование не позволит заметно ускорить запросы только с city_id.
o Рекомендуется: если однозначных полей для бакетирования нет, используйте случайное бакетирование, хотя при этом вы не получите преимущества усечения бакетов.
o Обязательно: если в запросе JOIN несколько таблиц по 1000 и более строк каждая, используйте функцию Colocate join.
Типы полей
Рекомендации по индексированию
o Подходит для столбцов с кардинальностью от 10 000 до 100 000.
o Подходит для столбцов, в запросы к которым входят условия равенства (=) или диапазон ([NOT] IN).
o Не подходит для типов данных FLOAT, DOUBLE, BOOLEAN и DECIMAL.
o Подходит для столбцов с кардинальностью более 100 000 и низким уровнем дублирования.
o Подходит для запросов с условиями in и =.
o Не подходит для типов данных TINYINT, FLOAT, DOUBLE и DECIMAL.
o В таблицах фактов и моделях с первичным ключом у всех столбцов могут быть битовые индексы. В агрегированных и часто обновляемых таблицах битовые индексы поддерживаются только в ключевых столбцах.
В третьей статье серии вы узнаете о загрузке данных в Селену, используя механизмы StarRocks.
- Рекомендуется: создавайте партиции на основе неизменяемого столбца времени для фильтрации WHERE.
- Рекомендуется: выбирайте динамические партиции в сценариях, когда у данных есть срок действия.
- Обязательно: используйте разный подход для очевидно «горячих» и «холодных» данных, например, можно ежедневно партиционировать часто обновляемые данные за последнюю неделю.
- Обязательно: ограничьте размер партиции: не более 100 ГБ.
- Обязательно: разделяйте на партиции таблицы размером более 50 ГБ или 5 млн строк.
- Рекомендуется: создавайте партиции по необходимости; не создавайте слишком много пустых партиций, чтобы лишние метаданные не занимали память на фронтенде.
- Поддерживаемые типы партиций: время (диапазон, выражение), строка (список), число (диапазон, список).
- По умолчанию поддерживается до 1024 партиций. Это значение можно изменить, но обычно это не требуется.
Рекомендации по бакетированию
- Обязательно: в рабочем окружении используйте три реплики.
- Как рассчитать бакеты:
o Обязательно: один бакет примерно соответствует 1 ГБ, объем необработанных данных — 10 ГБ (коэффициент сжатия: 7–10 к 1). Если расчетное количество бакетов меньше числа бэкенд-узлов, фактическое количество бакетов должно равняться числу бэкенд-узлов (например, 6 узлов и 6 бакетов).
o Обязательно: на используйте динамическое бакетирование для таблиц без партиций; рассчитайте число бакетов по фактическому объему данных.
o Обязательно: избегайте динамического бакетирования, если партиции сильно различаются по размеру.
- Как предотвратить неравномерное распределение данных при бакетировании:
o Рекомендуется: если столбец содержит мало повторяющихся данных (например, user_id, transaction_id) и часто используется в условиях WHERE, выберите его для бакетирования.
o Рекомендуется: если запросы часто обращаются к столбцам city_id и site_id вместе, и у city_id низкая кардинальность, использование столбца city_id для бакетирования приведет к значительному перекосу. В этом случае лучше комбинировать city_id и site_id. Правда, в таком случае бакетирование не позволит заметно ускорить запросы только с city_id.
o Рекомендуется: если однозначных полей для бакетирования нет, используйте случайное бакетирование, хотя при этом вы не получите преимущества усечения бакетов.
o Обязательно: если в запросе JOIN несколько таблиц по 1000 и более строк каждая, используйте функцию Colocate join.
Типы полей
- Рекомендуется: избегайте значений null.
- Обязательно: проверьте типы данных во временных и числовых столбцах. Например, если хранить дату и время "2024-01-01 00:00:00" в VARCHAR, значительно возрастут затраты вычислительных ресурсов, а встроенные оптимизации, такие как структура Zone Map, не дадут преимуществ.
Рекомендации по индексированию
o Подходит для столбцов с кардинальностью от 10 000 до 100 000.
o Подходит для столбцов, в запросы к которым входят условия равенства (=) или диапазон ([NOT] IN).
o Не подходит для типов данных FLOAT, DOUBLE, BOOLEAN и DECIMAL.
o Подходит для столбцов с кардинальностью более 100 000 и низким уровнем дублирования.
o Подходит для запросов с условиями in и =.
o Не подходит для типов данных TINYINT, FLOAT, DOUBLE и DECIMAL.
o В таблицах фактов и моделях с первичным ключом у всех столбцов могут быть битовые индексы. В агрегированных и часто обновляемых таблицах битовые индексы поддерживаются только в ключевых столбцах.
В третьей статье серии вы узнаете о загрузке данных в Селену, используя механизмы StarRocks.