HLL (HyperLogLog)
HLL используется для приблизительного подсчета уникальных значений.
HLL позволяет разрабатывать программы на основе алгоритма HyperLogLog. Он используется для хранения промежуточных результатов вычислений HyperLogLog. Его можно использовать только в качестве типа столбца значений таблицы. HLL уменьшает объем данных через агрегацию для ускорения процесса запроса. В оценочных результатах может быть отклонение в 1%.
Столбец HLL генерируется на основе импортированных данных или данных из других столбцов. При импорте данных функция hll_hash указывает, какой столбец будет использоваться для генерации столбца HLL. HLL часто используется для замены COUNT DISTINCT и быстрого вычисления уникальных просмотров (UV) с rollup.
Объем хранения, используемый HLL, определяется уникальными значениями в хеш-значении. Объем хранения варьируется в зависимости от трех условий:
- HLL пуст. В HLL не вставлено ни одного значения, и стоимость хранения минимальна - 80 байт.
- Количество уникальных хеш-значений в HLL меньше или равно 160. Максимальная стоимость хранения составляет 1360 байт (80 + 160 * 8 = 1360).
- Количество уникальных хеш-значений в HLL больше 160. Стоимость хранения фиксирована и составляет 16 464 байта (80 + 16 * 1024 = 16464).
В реальных бизнес-сценариях объем данных и распределение данных влияют на использование памяти при запросах и точность приблизительного результата. Необходимо учитывать эти два фактора:
- Объем данных: HLL возвращает приблизительное значение. Больший объем данных дает более точный результат. Меньший объем данных приводит к большему отклонению.
- Распределение данных: В случае большого объема данных и столбца измерения с высокой кардинальностью для GROUP BY вычисление данных будет использовать больше памяти. HLL не рекомендуется в этой ситуации. Он рекомендуется при выполнении count distinct без группировки или GROUP BY по столбцам измерений с низкой кардинальностью.
- Гранулярность запроса: Если вы запрашиваете данные с большой гранулярностью запроса, рекомендуется использовать Aggregate-таблицу или материализованное представление для предварительной агрегации данных для уменьшения объема данных.
Связанные функции
-
HLL_UNION_AGG(hll): Это агрегатная функция, используемая для оценки кардинальности всех данных, удовлетворяющих условиям. Также может использоваться для анализа функций. Она поддерживает только окно по умолчанию и не поддерживает предложение window.
-
HLL_RAW_AGG(hll): Это агрегатная функция, используемая для агрегации полей типа hll и возвращающая тип hll.
-
HLL_CARDINALITY(hll): Эта функция используется для оценки кардинальности одного столбца hll.
-
HLL_HASH(column_name): Генерирует тип столбца HLL и используется для вставки или импорта. См. инструкции по использованию импорта.
-
HLL_EMPTY: Генерирует пустой столбец HLL и используется для заполнения значений по умолчанию при вставке или импорте. См. инструкции по использованию импорта.
Примеры
-
Создайте таблицу со столбцами HLL
set1иset2.create table test(
dt date,
id int,
name char(10),
province char(10),
os char(1),
set1 hll hll_union,
set2 hll hll_union)
distributed by hash(id); -
Загрузите данные с помощью Stream Load.
a. Используйте столбцы таблицы для генерации столбца HLL.
curl --location-trusted -uname:password -T data -H "label:load_1" \
-H "columns:dt, id, name, province, os, set1=hll_hash(id), set2=hll_hash(name)"
http://host/api/test_db/test/_stream_load
b. Используйте столбцы данных для генерации столбца HLL.
curl --location-trusted -uname:password -T data -H "label:load_1" \
-H "columns:dt, id, name, province, sex, cuid, os, set1=hll_hash(cuid), set2=hll_hash(os)"
http://host/api/test_db/test/_stream_load -
Агрегируйте данные одним из трех способов: (Без агрегации прямой запрос к базовой таблице может быть таким же медленным, как использование approx_count_distinct)
-- a. Создайте rollup для агрегации столбца HLL.
alter table test add rollup test_rollup(dt, set1);
-- b. Создайте другую таблицу для вычисления uv и вставьте в нее данные
create table test_uv(
dt date,
id int
uv_set hll hll_union)
distributed by hash(id);
insert into test_uv select dt, id, set1 from test;
-- c. Создайте другую таблицу для вычисления UV. Вставьте данные и сгенерируйте столбец HLL, тестируя другие столбцы через hll_hash.
create table test_uv(
dt date,
id int,
id_set hll hll_union)
distributed by hash(id);
insert into test_uv select dt, id, hll_hash(id) from test; -
Запросите данные. Столбцы HLL не поддерживают прямой запрос к их исходным значениям. Их можно запрашивать с помощью соответствующих функций.
a. Вычислите общий UV.
select HLL_UNION_AGG(uv_set) from test_uv;
b. Вычислите UV для каждого дня.
select dt, HLL_CARDINALITY(uv_set) from test_uv;
c. Вычислите агрегированное значение set1 в таблице test.
select dt, HLL_CARDINALITY(uv) from (select dt, HLL_RAW_AGG(set1) as uv from test group by dt) tmp;
select dt, HLL_UNION_AGG(set1) as uv from test group by dt;