Bitmap индексы
В этой теме описывается, как создавать и управлять bitmap индексом, а также варианты использования.
Введение
Bitmap индекс - это специальный индекс базы данных, который использует bitmap, который представляет собой массив битов. Бит всегда находится в одном из двух значений: 0 и 1. Каждый бит в bitmap соответствует одной строке в таблице. Значение каждого бита зависит от значения соответствующей строки.
Bitmap индекс может помочь улучшить производительность запросов по заданному столбцу. Если условия фильтра запроса соответствуют prefix индексу, это может значительно улучшить эффективность запроса и быстро вернуть результаты. Однако таблица может иметь только один prefix индекс. Если условия фильтра запроса не включают prefix prefix индекса, bitmap индекс может быть создан для этого столбца для улучшения эффективности запроса.
Как разработать bitmap индекс для ускорения запросов
Основные соображения при выборе bitmap индекса - это cardinality столбца и эффект фильтрации bitmap индекса на запросы. Вопреки распространенному мнению, bitmap индексы в Selena больше подходят для запросов к столбцам с высокой cardinality и запросов к комбинации нескольких столбцов с низкой cardinality. Кроме того, bitmap индексы должны эффективно фильтровать данные, потенциально отфильтровывая по крайней мере 999/1000 данных, тем самым уменьшая объем данных Page, которые необходимо прочитать.
Для запросов к одному столбцу с низкой cardinality эффект фильтрации bitmap индекса плохой, поскольку необходимо прочитать слишком много строк, разбросанных по нескольким Pages.
Вам нужно учитывать стоимость загрузки данных при оценке эффекта фильтрации bitmap индексов на запросы. В Selena базовые данные организованы и загружаются по Pages (размер по умолчанию 64K). Стоимость загрузки данных включает время загрузки Pages с диска, распаковки Pages и декодирования.
Однако чрезмерно высокая cardinality также может вызвать проблемы, такие как занятие большего дискового пространства, и поскольку bitmap индексы должны создаваться во время загрузки данных, частая загрузка данных может влиять на производительность загрузки.
Кроме того, следует учитывать накладные расходы на загрузку bitmap индексов во время запросов. Во время запроса bitmap индексы загружаются по требованию, и чем больше значение количество значений столбца, участвующих в условиях запроса/cardinality x bitmap индекс, тем больше накладные расходы на загрузку bitmap индексов во время запросов.
Чтобы определить подходящую cardinality и условия запроса для bitmap индексов, рекомендуется обратиться к Тесту производительности bitmap индекса в этой теме для проведения тестов производительности. Вы можете использовать фактические бизнес-данные и запросы для создания bitmap индексов на столбцах с различной cardinality, чтобы проанализировать эффект фильтрации bitmap индексов на запросы (по крайней мере, отфильтровывая 999/1000 данных), использование дискового пространства, влияние на производительность загрузки и накладные расходы на загрузку bitmap индексов во время запросов.
Selena имеет встроенный механизм адаптивного выбора bitmap индексов. Если bitmap индекс не может ускорить запросы, например, если он не может отфильтровать много Pages, или накладные расходы на загрузку bitmap индексов во время запросов высоки, он не будет использоваться во время запроса, поэтому производительность запроса не будет существенно затронута.
Адаптивный выбор bitmap индексов
Selena может адаптивно выбирать, использовать ли bitmap индекс на основе cardinality столбца и условий запроса. Если bitmap индекс не эффективно фильтрует много Pages или накладные расходы на загрузку bitmap индексов во время запросов высоки, Selena не будет использовать bitmap индекс по умолчанию, чтобы избежать ухудшения производительности запроса.
Selena определяет, использовать ли bitmap индекс, на основе отношения количества значений, участвующих в условии запроса, к cardinality столбца. Как правило, чем меньше это отношение, тем лучше эффект фильтрации bitmap индекса. Таким образом, Selena использует bitmap_max_filter_ratio/1000 в качестве порога. Когда количество значений в условии фильтра/cardinality столбца меньше bitmap_max_filter_ratio/1000, bitmap индекс будет использоваться. Значение по умолчанию для bitmap_max_filter_ratio равно 1.
Возьмем в качестве примера запрос на основе одного столбца, такой как SELECT * FROM employees WHERE gender = 'male';. Столбец gender в таблице employees имеет значения 'male' и 'female', поэтому cardinality равна 2 (два различных значения). Условие запроса включает одно значение, поэтому отношение составляет 1/2, что больше 1/1000. Следовательно, это т запрос не будет использовать bitmap индекс.
Возьмем другой запрос на основе комбинации нескольких столбцов в качестве примера, такой как SELECT * FROM employees WHERE gender = 'male' AND city IN ('Beijing', 'Shanghai');. Cardinality столбца city составляет 10 000, и условие запроса включает два значения, поэтому отношение рассчитывается как (1*2)/(2*10000), что меньше 1/1000. Следовательно, этот запрос будет использовать bitmap индекс.
Диапазон значений для bitmap_max_filter_ratio составляет 1-1000. Если bitmap_max_filter_ratio установлено в 1000, любой запрос к столбцу с bitmap индексом будет принудительно использовать bitmap индекс.
Преимущества
- Bitmap индексы могут быстро определить номера строк запрошенн ых значений столбцов, подходят для точечных запросов или запросов с небольшим диапазоном.
- Bitmap индексы могут оптимизировать многомерные запросы, включающие операции объединения и пересечения (операции
ORиAND).
Рекомендации
Запросы, которые могут быть оптимизированы
Bitmap индексы подходят для оптимизации запросов на равенство =, запросов диапазона [NOT] IN, запросов >, >=, <, <= и запросов IS NULL. Они не подходят для оптимизации запросов != и [NOT] LIKE.
Поддерживаемые столбцы и типы данных
Bitmap индексы могут быть созданы на всех столбцах в primary key и duplicate key таблицах, и на ключевых столбцах в aggregate и unique key таблицах. Bitmap индексы могут быть созданы на столбцах следующих типов данных:
- Типы дат: DATE, DATETIME.
- Числовые типы: TINYINT, SMALLINT, INT, BIGINT, LARGEINT, DECIMAL, BOOLEAN.
- Строковые типы: CHAR, STRING, VARCHAR.
- Другие типы: HLL.
Базовые операции
Создание индекса
-
Создание bitmap индекса во время создания таблицы.
CREATE TABLE `lineorder_partial` (
`lo_orderkey` int(11) NOT NULL COMMENT "",
`lo_orderdate` int(11) NOT NULL COMMENT "",
`lo_orderpriority` varchar(16) NOT NULL COMMENT "",
`lo_quantity` int(11) NOT NULL COMMENT "",
`lo_revenue` int(11) NOT NULL COMMENT "",
INDEX lo_orderdate_index (lo_orderdate) USING BITMAP
) ENGINE=OLAP
DUPLICATE KEY(`lo_orderkey`)
DISTRIBUTED BY HASH(`lo_orderkey`) BUCKETS 1;В этом примере bitmap индекс с име нем
lo_orderdate_indexсоздается на столбцеlo_orderdate. Требования к именованию bitmap индексов можно найти в Системные ограничения. Идентичные bitmap индексы не могут быть созданы в одной таблице.Несколько bitmap индексов могут быть созданы для нескольких столбцов, разделенных запятыми (,).
примечаниеДля дополнительных параметров создания таблицы обратитесь к CREATE TABLE.
-
CREATE INDEXможет использоваться для создания bitmap индекса после создания таблицы. Для подробных описаний параметров и примеров обратитесь к CREATE INDEX.CREATE INDEX lo_quantity_index ON lineorder_partial (lo_quantity) USING BITMAP;
Прогресс создания индекса
Создание bitmap индекса - это асинхронный процесс. После выполнения оператора создания индекса вы можете проверить прогресс создания индекса с помощью команды SHOW ALTER TABLE. Когда поле State в возвращаемом значении показывает FINISHED, индекс успешно создан.
SHOW ALTER TABLE COLUMN;
Каждая таблица может иметь только одну выполняющуюся задачу Schema Change одновременно. Вы не можете создать новый bitmap индекс, пока текущий bitmap индекс не будет создан.
Просмотр индекса
Просмотр всех bitmap индексов для указанной таблицы. Для подробных параметров и возвращаемых результатов обратитесь к SHOW INDEX.
SHOW INDEXES FROM lineorder_partial;
Создание bitmap индекса - это асинхронный процесс. Используя приведенный выше оператор, вы можете просматривать только индексы, которые успешно завершили создание.
Удаление индекса
Удаление bitmap индекса для указанной таблицы. Для подробных параметров и примеров обратитесь к DROP INDEX.
DROP INDEX lo_orderdate_index ON lineorder_partial;
Проверка того, ускоряет ли bitmap индекс запросы
Проверьте поле BitmapIndexFilterRows в Profile запроса. Для информации о просмотре Profile обратитесь к Анализ запросов.
Тест производительности bitmap индекса
Цель тестирования
Анализ эффекта фильтрации и других влияний, таких как использование диска, bitmap индексов на запросы с различной cardinality:
- Запрос к одному столбцу с низкой cardinality
- Запрос к комбинации нескольких столбцов с низкой cardinality
- Запрос к одному столбцу с высокой cardinality
Этот раздел также сравнивает производительност ь между всегда использующим bitmap индекс и адаптивным использованием bitmap индексов для проверки эффективности адаптивного выбора bitmap индексов Selena.
Создание таблицы и bitmap индекса
Чтобы избежать кэширования данных Page, влияющего на производительность запроса, убедитесь, что конфигурационный параметр BE disable_storage установлен в true.
В этом разделе в качестве примера используется таблица lineorder (SSB 20G).
-
Исходная таблица (без bitmap индексов) в качестве эталона
CREATE TABLE `lineorder_without_index` (
`lo_orderkey` int(11) NOT NULL COMMENT "",
`lo_linenumber` int(11) NOT NULL COMMENT "",
`lo_custkey` int(11) NOT NULL COMMENT "",
`lo_partkey` int(11) NOT NULL COMMENT "",
`lo_suppkey` int(11) NOT NULL COMMENT "",
`lo_orderdate` int(11) NOT NULL COMMENT "",
`lo_orderpriority` varchar(16) NOT NULL COMMENT "",
`lo_shippriority` int(11) NOT NULL COMMENT "",
`lo_quantity` int(11) NOT NULL COMMENT "",
`lo_extendedprice` int(11) NOT NULL COMMENT "",
`lo_ordtotalprice` int(11) NOT NULL COMMENT "",
`lo_discount` int(11) NOT NULL COMMENT "",
`lo_revenue` int(11) NOT NULL COMMENT "",
`lo_supplycost` int(11) NOT NULL COMMENT "",
`lo_tax` int(11) NOT NULL COMMENT "",
`lo_commitdate` int(11) NOT NULL COMMENT "",
`lo_shipmode` varchar(11) NOT NULL COMMENT ""
) ENGINE=OLAP
DUPLICATE KEY(`lo_orderkey`)
DISTRIBUTED BY HASH(`lo_orderkey`) BUCKETS 1; -
Таблица с bitmap индексами: Bitmap индексы созданы на основе
lo_shipmode,lo_quantity,lo_discount,lo_orderdate,lo_taxиlo_partkey.CREATE TABLE `lineorder_with_index` (
`lo_orderkey` int(11) NOT NULL COMMENT "",
`lo_linenumber` int(11) NOT NULL COMMENT "",
`lo_custkey` int(11) NOT NULL COMMENT "",
`lo_partkey` int(11) NOT NULL COMMENT "",
`lo_suppkey` int(11) NOT NULL COMMENT "",
`lo_orderdate` int(11) NOT NULL COMMENT "",
`lo_orderpriority` varchar(16) NOT NULL COMMENT "",
`lo_shippriority` int(11) NOT NULL COMMENT "",
`lo_quantity` int(11) NOT NULL COMMENT "",
`lo_extendedprice` int(11) NOT NULL COMMENT "",
`lo_ordtotalprice` int(11) NOT NULL COMMENT "",
`lo_discount` int(11) NOT NULL COMMENT "",
`lo_revenue` int(11) NOT NULL COMMENT "",
`lo_supplycost` int(11) NOT NULL COMMENT "",
`lo_tax` int(11) NOT NULL COMMENT "",
`lo_commitdate` int(11) NOT NULL COMMENT "",
`lo_shipmode` varchar(11) NOT NULL COMMENT "",
INDEX i_shipmode (`lo_shipmode`) USING BITMAP,
INDEX i_quantity (`lo_quantity`) USING BITMAP,
INDEX i_discount (`lo_discount`) USING BITMAP,
INDEX i_orderdate (`lo_orderdate`) USING BITMAP,
INDEX i_tax (`lo_tax`) USING BITMAP,
INDEX i_partkey (`lo_partkey`) USING BITMAP
) ENGINE=OLAP
DUPLICATE KEY(`lo_orderkey`)
DISTRIBUTED BY HASH(`lo_orderkey`) BUCKETS 1;
Использование дискового пространства bitmap индексами
lo_shipmode: Строковый тип, cardinality 7, занимает 130Mlo_quantity: Целочисленный тип, cardinality 50, занимает 291Mlo_discount: Целочисленный тип, cardinality 11, занимает 198Mlo_orderdate: Целочисленный тип, cardinality 2406, занимает 191Mlo_tax: Целочисленный тип, cardinality 9, занимает 160Mlo_partkey: Целочисленный тип, cardinality 600 000, занимает 601M