Перейти к основному содержимому
Версия: 2.0.x

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 и используется для заполнения значений по умолчанию при вставке или импорте. См. инструкции по использованию импорта.

Примеры

  1. Создайте таблицу со столбцами 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);
  2. Загрузите данные с помощью 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
  3. Агрегируйте данные одним из трех способов: (Без агрегации прямой запрос к базовой таблице может быть таким же медленным, как использование 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;
  4. Запросите данные. Столбцы 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;