Префиксный индекс и ключ сортировки
Префиксный индекс представляет собой разреженный индекс, который Apache Doris автоматически создаёт и поддерживает. Он быстро находит блоки данных по первым 36 байтам ключа сортировки и не требует ручного создания. Выбор подходящего ключа сортировки при проектировании схемы таблицы значительно ускоряет запросы на равенство и диапазонные запросы с условиями в WHERE.
Принцип работы

Ключ сортировки
Apache Doris хранит данные в упорядоченной структуре, похожей на SSTable (Sorted String Table). Данные могут храниться с сортировкой по одному или нескольким заданным столбцам. Эти столбцы сортировки называются ключом сортировки.
В разных моделях данных ключ сортировки определяется по-разному:
| Модель данных | Источник ключа сортировки |
|---|---|
| Aggregate | Aggregate Key в операторе CREATE TABLE |
| Unique | Unique Key в операторе CREATE TABLE |
| Duplicate | Duplicate Key в операторе CREATE TABLE |
Если условие WHERE в запросе охватывает столбцы сортировки, ключ сортировки позволяет Doris быстро перейти к соответствующему диапазону данных и избежать полного сканирования таблицы. Это снижает сложность поиска и ускоряет запрос.
Префиксный индекс
На основе ключа сортировки Apache Doris также создаёт префиксный индекс:
- Каждые несколько строк таблицы образуют логический блок данных (Data Block).
- Каждому блоку данных соответствует только одна запись в таблице префиксного индекса. Эта запись представляет собой префикс, полученный объединением значений столбцов сортировки первой строки блока, длиной не более 36 байт.
- Благодаря небольшому размеру префиксный индекс может целиком храниться в кэше в памяти. Он быстро определяет номер начальной строки нужного блока данных и существенно повышает эффективность запросов.
Правило усечения по лимиту в 36 байт
Префиксный индекс использует в качестве содержимого индекса первые 36 байт значений столбцов сортировки строки, но немедленно выполняет усечение, когда встречает столбец VARCHAR:
- Когда при объединении значений столбцов сортировки встречается столбец
VARCHAR, усечение выполняется в конце этого столбца независимо от того, набраны ли 36 байт. - Если уже первый столбец имеет тип
VARCHAR, усечение выполняется в конце этого столбца, даже если его длина меньше 36 байт. Последующие столбцы в префиксный индекс не добавляются.
Сценарии применения
Префиксный индекс в основном предназначен для следующих сценариев запросов:
- Запросы на равенство:
col = value,col IN (...) - Диапазонные запросы:
col > value,BETWEEN ... AND ...и подобные условия
Если условие WHERE охватывает префикс ключа сортировки, то есть несколько крайних левых столбцов начиная с первого, префиксный индекс может ускорить запрос.
Рекомендации по проектированию схемы таблицы
У таблицы может быть только одно определение ключа сортировки, поэтому таблица может иметь только один набор префиксных индексов. Выбор ключа сортировки при создании таблицы напрямую определяет, насколько префиксный индекс ускорит запросы. Учитывайте следующие рекомендации:
- Выбирайте в качестве ключевых столбцов прежде всего те, которые чаще всего встречаются в условиях фильтрации
WHERE. - Размещайте чаще используемые в запросах столбцы в начале, поскольку префиксный индекс работает только для условий, которые последовательно охватывают столбцы начиная с крайнего левого.
- С осторожностью размещайте столбцы
VARCHARв начале ключа сортировки, чтобы избежать усечения, из-за которого последующие столбцы не попадут в префиксный индекс.
Если для часто используемого условия запроса не удаётся задействовать префиксный индекс изменением ключа сортировки, см. раздел Альтернативы, если префиксный индекс не применим ниже.
Примеры использования
Пример 1: префиксный индекс без усечения
Для приведённого ниже ключа сортировки префиксный индекс имеет вид user_id (8 Bytes) + age (4 Bytes) + message (first 20 Bytes), а его общая длина составляет 32 байта:
| Имя столбца | Тип |
|---|---|
| user_id | BIGINT |
| age | INT |
| message | VARCHAR(100) |
| max_dwell_time | DATETIME |
| min_dwell_time | DATETIME |
Пример 2: первый столбец имеет тип VARCHAR и вызывает усечение
Для приведённого ниже ключа сортировки префиксный индекс содержит только user_name (20 Bytes). Хотя общая длина ещё не достигла 36 байт, усечение выполняется сразу, поскольку первый столбец имеет тип VARCHAR. Последующие столбцы в префиксный индекс не добавляются:
| Имя столбца | Тип |
|---|---|
| user_name | VARCHAR(20) |
| age | INT |
| message | VARCHAR(100) |
| max_dwell_time | DATETIME |
| min_dwell_time | DATETIME |
Пример 3: запросы с использованием префиксного индекса и без него
Для схемы таблицы из примера 1:
-
Префиксный индекс используется (условие охватывает два крайних левых столбца сортировки, что обеспечивает высокую эффективность):
SELECT * FROM table WHERE user_id = 1829239 AND age = 20; -
Префиксный индекс не используется (условие пропускает
user_id, поэтому префикс нельзя использовать для поиска нужных данных):SELECT * FROM table WHERE age = 20;
Таким образом, правильный выбор порядка столбцов при создании таблицы значительно повышает эффективность запросов.
Проверка эффективности индекса
Префиксный индекс применяется автоматически, когда он может ускорить запрос, и не требует специального синтаксиса. Проверить ускорение можно с помощью следующей метрики в профиле запроса:
| Метрика | Значение |
|---|---|
RowsKeyRangeFiltered | Количество строк, отфильтрованных префиксным индексом. Сравните его с другими метриками Rows*, чтобы оценить эффективность фильтрации с помощью индекса. |
Альтернативы, если префиксный индекс не применим
Если часто используемое условие запроса не позволяет задействовать префиксный индекс, например когда столбцы, по которым обычно выполняется фильтрация, не образуют префикс ключа сортировки, рассмотрите следующие два варианта:
- Создайте инвертированный индекс: таблица может иметь несколько инвертированных индексов, что позволяет гибко охватывать столбцы, используемые в разных условиях запросов.
- Используйте материализованное представление на основе одной таблицы (модель Duplicate): создав строго согласованное синхронное материализованное представление на основе одной таблицы с другим порядком столбцов, можно косвенно получить несколько наборов префиксных индексов.
Часто задаваемые вопросы
Вопрос 1: нужно ли создавать префиксный индекс вручную?
Нет. При создании таблицы Doris автоматически использует первые 36 байт ключа сортировки в качестве префиксного индекса. Отдельного синтаксиса DDL для него нет.
Вопрос 2: может ли одна таблица иметь несколько наборов префиксных индексов?
Нет. Поскольку ключ сортировки у таблицы только один, она может иметь только один набор префиксных индексов. Если требуется несколько наборов, используйте инвертированные индексы или материализованные представления.
Вопрос 3: почему мой префиксный индекс намного короче, чем ожидалось?
Самая частая причина заключается в том, что столбец VARCHAR расположен близко к началу ключа сортировки и вызывает усечение. Размещайте типы фиксированной длины, такие как BIGINT, INT, DATETIME и TIMESTAMP_NS, в начале ключа сортировки.
Вопрос 4: может ли префиксный индекс ускорять запросы с LIKE или текстовый поиск?
Нет. Для нечёткого сопоставления с помощью LIKE и полнотекстового поиска используйте индекс NGram BloomFilter и инвертированный индекс соответственно.