Перейти к основному содержимому

HLL (HyperLogLog)

HLL используется для приблизительного подсчета уникальных значений.

HLL позволяет разрабатывать программы на основе алгоритма HyperLogLog. Он используется для хранения промежуточных результатов процесса вычислений HyperLogLog. Может использоваться только как тип столбца значений таблицы. HLL уменьшает объем данных за счет агрегации для ускорения процесса запросов. В оценочных результатах может быть отклонение в 1%.

Столбец HLL генерируется на основе импортированных данных или данных из других столбцов. При импорте данных функция hll_hash указывает, какой столбец будет использоваться для генерации столбца HLL. HLL часто используется для замены COUNT DISTINCT и быстрого вычисления уникальных просмотров (UV) с накоплением.

Пространство хранения, используемое 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;