Ускорение COUNT(DISTINCT) и Join с помощью AUTO INCREMENT и глобального словаря
В этой теме описывается, как ускорить вычисление COUNT(DISTINCT) и операции Join с использованием столбцов AUTO INCREMENT и глобального словаря.
Сценарии использования
-
Сценарий 1: Предположим, вам нужно выполнить точную дедупликацию на массивных данных (например, розничные заказы или заказы на доставку). Однако столбец для дедупликации имеет тип STRING, что может привести к неоптимальной производительности при подсчёте. Например, в таблице
ordersстолбецorder_uuid, представляющий идентификатор заказа, имеет тип STRING, обычно размером от 32 до 36 байт, генерируемый функциейUUID()или аналогичными. В этом случае COUNT(DISTINCT) по STRING-столбцуorder_uuidс запросом видаSELECT count(DISTINCT order_uuid) FROM orders WHERE create_date >= CURDATE();может не обеспечить удовлет ворительную производительность. Использование INTEGER-столбца для точной дедупликации значительно повысит производительность. -
Сценарий 2: Предположим, вы хотите ускорить точную дедупликацию в многомерном анализе с использованием bitmap-функций. Функция
bitmap_count()требует INTEGER на входе, но если столбец для дедупликации имеет тип STRING, вам нужно использовать функциюbitmap_hash(). Это может привести к приблизительным, немного заниженным результатам дедупликации, а также может снизить производительность запросов и увеличить требования к хранилищу, поскольку INTEGER-значения, генерируемые bitmap_hash(), более рассеяны по сравнению с последовательно присвоенными INTEGER-значениями. -
Сценарий 3: Предположим, вам нужно запросить количество заказов с коротким промежутком времени между размещением и оплатой заказа, где время размещения и оплаты заказа могут храниться в разных таблицах, поддерживаемых разными бизнес-командами. Вам может потребоваться объединить эти таблицы по идентификатору заказа, а затем выполнить дедупликацию заказов. Наприм ер:
SELECT count(distinct order_uuid)
FROM orders_t1 as t1 JOIN orders_t2 as t2
ON t1.order_uuid = t2.order_uuid
WHERE t2.payment_time - t1.create_time <= 3600
AND create_date >= CURDATE();Однако использование STRING-столбца
order_uuidдля соединений менее эффективно, чем использование INTEGER-столбца.
Подход к оптимизации
Для решения проблем в вышеуказанных сценариях подход к оптимизации включает загрузку данных заказов в целевую таблицу и установление сопоставления между STRING- и INTEGER-значениями. Последующий анализ запросов будет основан на INTEGER-столбце. Этот подход можно разделить на следующие этапы:
-
Этап 1: Создание глобального словаря и установление сопоставления между STRING- и INTEGER-значениями. В этом словаре ключевой столбец имеет тип STRING, а столбец значений — тип AUTO INCREMENT INTEGER. При загрузке данных система автоматически генерирует уникальный идентификатор для каждого STRING-значения, создавая сопоставление между STRING- и INTEGER-значениями.
-
Этап 2: Загрузка связи между данными заказов и глобальным словарём в целевую таблицу.
-
Этап 3: Использование INTEGER-столбца из целевой таблицы для точной дедупликации или соединений при последующем анализе запросов, что может значительно повысить производительность.
-
Этап 4: Для дальнейшей оптимизации производительности можно использовать bitmap-функции на INTEGER-столбце для ускорения точной дедупликации.
Решение
До версии v1.5.2 этап 2 мог быть реализован двумя способами:
- Использование внешней таблицы или внутренней таблицы в качестве промежуточной таблицы для соединения с таблицей словаря для получения соответствующего идентификатора словаря перед загрузкой.
- Использование таблицы Primary Key для загрузки данных, а затем использование оператора UPDATE с операцией JOIN для обновления идентификатора словаря. Однако этот процесс загрузки данных может быть неудобным и имеет много ограничений.
Начиная с версии v1.5.2, Selena представила функцию dict_mapping(), позволяющую определять столбец идентификатора словаря в целевой таблице как вычисляемый столбец с использованием выражения dict_mapping(). Последующие задачи загрузки данных обрабатываются как обычная загрузка данных, без необходимости использования операторов UPDATE с операциями JOIN для записи идентификаторов словаря. Во время загрузки данных система автоматически связывает исходную таблицу с таблицей словаря и вставляет соответствующий идентификатор словаря, что значительно упрощает процесс загрузки данных с глобальной таблицей словаря, независимо от типов таблиц и с поддержкой различных методов загрузки.