hll 拡張機能は、HyperLogLog (HLL) データ型を PolarDB に追加し、メモリ効率の高い、個別要素数の高速な推定を可能にします。1,280 バイトの HLL データを使用することで、数十億もの個別値を正確に推定できます。これは、インターネット広告におけるページビュー (PV) やユニークビジター (UV) のカウントなど、大規模な分析に役立ちます。
COUNT DISTINCT の代わりに HLL を使用する理由
COUNT DISTINCT は、「今日のユニークユーザー数は何人か?」といった単一の質問に一度に答えることしかできません。「今週のユニークユーザー数は何人か?」という質問に答えるには、すべての生データを再スキャンする必要があります。
HLL スケッチは加算的です。日次の HLL 集計を一度保存すれば、生データを再読み取りすることなく、任意のタイムウィンドウでそれらを統合できます。週次ユニーク数、月次ユニーク数、7 日間のスライドウィンドウ、離脱ユーザー数などはすべて、単一の事前集計テーブルから取得でき、数分かかっていた処理がミリ秒単位で完了します。
前提条件
作業を開始する前に、以下が満たされていることを確認してください:
PolarDB PostgreSQL 14 (カーネルマイナーバージョン 14.5.2.0 以降)、または PolarDB PostgreSQL 11 (カーネルマイナーバージョン 1.1.28 以降)
カーネルバージョンを確認するには、以下を実行します:
SHOW polar_version;拡張機能のインストール
CREATE EXTENSION hll;データ型
| データ型 | 説明 |
|---|---|
hll | HLL スケッチ。ハッシュ化された値のセットを、圧縮された確率的表現で格納します。 |
hll_hashval | ハッシュ化された要素。HLL スケッチに追加する前に、生データを hll_hashval にハッシュ化します。 |
演算子
hll 演算子
| 演算子 | 説明 | 例 |
|---|---|---|
= | 平等 | hll_add_agg(1::hll_hashval) = hll_add_agg(2::hll_hashval) |
!=、 <> | 非等価性 | — |
|| | HLL スケッチに要素を追加するか、2 つの HLL スケッチを統合します | hll_add_agg(1::hll_hashval) || hll_add_agg(2::hll_hashval) |
# | 個別要素数を推定します | #hll_add_agg(1::hll_hashval) |
hll_hashval 演算子
| 演算子 | 説明 |
|---|---|
= | 平等 |
!=、 <> | 非等価性 |
関数
ハッシュ関数
HLL スケッチに挿入する前に、生データを hll_hashval に変換します。
| 関数 | 入力型 | 例 |
|---|---|---|
hll_hash_boolean(val) | boolean | SELECT hll_hash_boolean(true); |
hll_hash_smallint(val) | smallint | — |
hll_hash_integer(val) | integer | SELECT hll_hash_integer(1); |
hll_hash_bigint(val) | bigint | — |
集計関数とセット関数
| 関数 | 説明 | 例 |
|---|---|---|
hll_add_agg(hll_hashval) | 集計関数。事前ハッシュ化された hll_hashval 入力を受け取り、それぞれを HLL スケッチに挿入します。 | SELECT hll_add_agg(1::hll_hashval); |
hll_union(hll, hll) | 2 つの HLL スケッチの和集合を返します。これは、事前集計された 2 つのスケッチを正確に統合する場合に使用します。 | SELECT hll_union(hll_add_agg(1::hll_hashval), hll_add_agg(2::hll_hashval)); |
hll_set_defaults(log2m, regwidth, expthresh, sparseon) | セッションのデフォルト HLL パラメーターを設定します。log2m はレジスタ数を制御します (値が大きいほど精度とメモリ使用量が高くなります)。regwidth はレジスタあたりのビット数を制御します。expthresh は明示的モードから確率的モードに切り替えるためのしきい値を制御します。sparseon はスパース表現を有効化します。 | SELECT hll_set_defaults(15, 5, -1, 1); |
hll_print(hll) | HLL スケッチに関するデバッグ情報を返します。 | SELECT hll_print(hll_add_agg(1::hll_hashval)); |
例:日次ユニークビジターの追跡
この例では、日次の HLL 集計の保存から、複数のタイムウィンドウにわたるユニークビジター数のクエリ実行まで、完全なワークフローを示します。
テーブルを作成し、集計データを挿入します:
CREATE TABLE access_date (acc_date DATE UNIQUE, userids hll);
-- 0 日目:ユーザー 1~10,000
INSERT INTO access_date
SELECT current_date, hll_add_agg(hll_hash_integer(user_id))
FROM generate_series(1, 10000) t(user_id);
-- 1 日前:ユーザー 5,000~20,000
INSERT INTO access_date
SELECT current_date - 1, hll_add_agg(hll_hash_integer(user_id))
FROM generate_series(5000, 20000) t(user_id);
-- 2 日前:ユーザー 9,000~40,000
INSERT INTO access_date
SELECT current_date - 2, hll_add_agg(hll_hash_integer(user_id))
FROM generate_series(9000, 40000) t(user_id);# (カーディナリティ) 演算子を使用して、日次ユニークビジター数をクエリします:
SELECT #userids FROM access_date WHERE acc_date = current_date;
-- ?column?
-- ------------------
-- 9725.852733707077
SELECT #userids FROM access_date WHERE acc_date = current_date - 1;
-- ?column?
-- ------------------
-- 14968.65968832792
SELECT #userids FROM access_date WHERE acc_date = current_date - 2;
-- ?column?
-- ------------------
-- 29361.520914991113複数の日にわたる HLL スケッチをマージして、複数日のウィンドウでのユニークビジター数をクエリします:
-- 0 日目と 1 日前を合わせたユニークビジター数
SELECT #hll_union(
(SELECT userids FROM access_date WHERE acc_date = current_date),
(SELECT userids FROM access_date WHERE acc_date = current_date - 1)
);拡張機能のアンインストール
DROP EXTENSION hll;