All Products
Search
Document Center

ApsaraDB RDS:Estimasi kardinalitas (hll)

Last Updated:Mar 29, 2026

Ekstensi hll menambahkan tipe data HyperLogLog ke ApsaraDB RDS for PostgreSQL, memungkinkan Anda memperkirakan jumlah nilai unik (kardinalitas) pada set data besar dengan tingkat kesalahan di bawah 1% dan penggunaan penyimpanan minimal. Satu nilai hll berukuran 1.280 byte dapat merepresentasikan miliaran elemen unik—sehingga sangat praktis untuk analitik skala tinggi seperti menghitung jumlah tayangan halaman (PV) dan pengunjung unik (UV).

Prasyarat

Sebelum memulai, pastikan bahwa:

  • Instans RDS Anda menjalankan PostgreSQL 11 atau versi yang lebih baru.

Ekstensi hll tidak didukung pada PostgreSQL 17.
  • Jika versi mesin utama Anda memenuhi persyaratan tetapi ekstensi tetap tidak tersedia, perbarui versi mesin minor. Lihat Perbarui versi mesin minor.

Kapan menggunakan hll alih-alih COUNT DISTINCT

COUNT DISTINCT hanya menjawab satu pertanyaan tetap per kueri: "Berapa banyak nilai unik yang muncul dalam set data ini?" Jika Anda perlu menjawab pertanyaan tersebut untuk berbagai rentang waktu—hari ini, minggu ini, 30 hari terakhir, atau jendela bergulir 7 hari—Anda harus memindai ulang data mentah untuk setiap kueri.

hll bekerja secara berbeda. Ekstensi ini menyimpan sketsa ringkas dari suatu set data. Setelah Anda menyimpan sketsa harian, Anda dapat melakukan union saat kueri untuk menjawab pertanyaan apa pun terkait rentang waktu tanpa menyentuh data mentah. Hal ini membuat hll sangat cocok untuk beban kerja analitik di mana:

  • Data event mentah terlalu besar untuk diagregasi berulang kali

  • Anda memerlukan jumlah UV atau PV untuk rentang tanggal arbitrer

  • Hasil perkiraan dapat diterima (akurasi dapat dikonfigurasi melalui hll_set_defaults)

Untuk algoritma lengkapnya, lihat HyperLogLog: the analysis of a near-optimal cardinality estimation algorithm. Untuk kode sumber ekstensi upstream, lihat citusdata/postgresql-hll.

Cara kerja hashing

Sebelum menambahkan nilai ke struktur hll, Anda harus meng-hash-nya menggunakan salah satu fungsi hll_hash_*. hll menyimpan nilai hash, bukan nilai mentah—dengan cara inilah hll mencapai ukuran ringkas sekaligus penyimpanan yang agnostik terhadap tipe data.

Mencoba menambahkan integer mentah tanpa hashing akan menghasilkan error:

SELECT 1234 || hll_empty();
-- ERROR: operator does not exist: integer || hll
-- HINT: No operator matches the given name and argument type(s).
--       You might need to add explicit type casts.

Selalu bungkus nilai input dengan pemanggilan hll_hash_* yang sesuai sebelum meneruskannya ke operasi hll.

Aktifkan ekstensi hll

Sambungkan ke database Anda dan jalankan:

CREATE EXTENSION hll;

Panduan cepat

Contoh berikut membangun set hll minimal langkah demi langkah, lalu mengambil kardinalitasnya.

-- Buat tabel dengan kolom hll
CREATE TABLE helloworld (id integer, visitors hll);

-- Masukkan hll kosong
INSERT INTO helloworld (id, visitors) VALUES (1, hll_empty());

-- Tambahkan integer yang telah di-hash (misalnya, ID pengguna numerik)
UPDATE helloworld
SET visitors = hll_add(visitors, hll_hash_integer(12345))
WHERE id = 1;

-- Tambahkan nilai teks yang telah di-hash (misalnya, token session)
UPDATE helloworld
SET visitors = hll_add(visitors, hll_hash_text('session-abc'))
WHERE id = 1;

-- Perkirakan jumlah nilai unik
SELECT hll_cardinality(visitors) FROM helloworld WHERE id = 1;
--  hll_cardinality
-- -----------------
--                2
-- (1 row)

Operasi dasar

Buat tabel dengan bidang hll:

create table agg (id int primary key, userids hll);

Konversi data INT ke data hll_hashval:

select 1::hll_hashval;

Perkirakan UV untuk rentang tanggal

Contoh ini menunjukkan pola analitik PV/UV yang umum. Ide utamanya: simpan satu sketsa hll per hari, lalu lakukan union sketsa saat kueri untuk menjawab pertanyaan apa pun terkait rentang tanggal.

Langkah 1: Buat tabel dan isi sketsa harian

CREATE TABLE access_date (acc_date date UNIQUE, userids hll);

-- Hari 0: pengguna 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);

-- Hari -1: pengguna 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);

-- Hari -2: pengguna 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);

Langkah 2: Kueri UV untuk satu hari

Operator # mengembalikan perkiraan kardinalitas secara langsung.

SELECT #userids FROM access_date WHERE acc_date = current_date;
--      ?column?
-- ------------------
--  9725.85273370708
-- (1 row)

SELECT #userids FROM access_date WHERE acc_date = current_date - 1;
--      ?column?
-- ------------------
--  14968.6596883279
-- (1 row)

SELECT #userids FROM access_date WHERE acc_date = current_date - 2;
--      ?column?
-- ------------------
--  29361.5209149911
-- (1 row)

Langkah 3: Kueri UV untuk rentang tanggal

Lakukan union sketsa harian terlebih dahulu, lalu perkirakan kardinalitas. Pendekatan ini secara tepat memperhitungkan pengguna yang muncul di beberapa hari.

-- Pengunjung unik selama 3 hari terakhir (menghapus duplikat lintas hari)
SELECT hll_cardinality(hll_union_agg(userids))
FROM access_date
WHERE acc_date >= current_date - 2;

Langkah 4: Hitung jendela UV bergulir 7 hari

Gunakan fungsi jendela untuk menghitung jumlah pengunjung unik bergulir setiap hari tanpa memindai ulang data mentah.

SELECT
    acc_date,
    #hll_union_agg(userids) OVER seven_days AS rolling_uv
FROM access_date
WINDOW seven_days AS (ORDER BY acc_date ASC ROWS 6 PRECEDING);

Referensi

Fungsi hash

Hash setiap nilai input sebelum menambahkannya ke struktur hll. Pilih fungsi yang sesuai dengan tipe data kolom Anda.

FunctionInput typeExample
hll_hash_booleanbooleanhll_hash_boolean(true)
hll_hash_smallintsmallinthll_hash_smallint(4)
hll_hash_integerintegerhll_hash_integer(21474836)
hll_hash_bigintbiginthll_hash_bigint(9007199254740992)
hll_hash_texttexthll_hash_text('user@example.com')

Semua fungsi mengembalikan hll_hashval, satu-satunya tipe yang diterima oleh operator dan fungsi agregat hll.

Operator

hll Operator

OperatorDescriptionExample
=Equalityhll_add_agg(1::hll_hashval) = hll_add_agg(2::hll_hashval)
!= / <>Inequality
||Union (gabungkan dua set hll)hll_add_agg(1::hll_hashval) || hll_add_agg(2::hll_hashval)
#Perkiraan kardinalitas#hll_add_agg(1::hll_hashval)

hll_hashval Operator

OperatorDescriptionExample
=Equality1::hll_hashval = 2::hll_hashval
!= / <>Inequality1::hll_hashval <> 2::hll_hashval

Fungsi agregat dan utilitas

FunctionDescriptionExample
hll_empty()Mengembalikan hll kosonghll_empty()
hll_add(hll, hll_hashval)Menambahkan nilai hash ke hllhll_add(set, hll_hash_integer(42))
hll_add_agg(hll_hashval)Agregat: membangun hll dari kumpulan nilai hashSELECT hll_add_agg(hll_hash_integer(user_id)) FROM events
hll_cardinality(hll)Mengembalikan perkiraan jumlah nilai unikSELECT hll_cardinality(visitors)
hll_union(hll, hll)Menggabungkan dua nilai hllhll_union(hll_add_agg(1::hll_hashval), hll_add_agg(2::hll_hashval))
hll_union_agg(hll)Agregat: menggabungkan beberapa nilai hllSELECT hll_union_agg(daily_sketch) FROM daily_uniques
hll_set_defaults(log2m, regwidth, expthresh, sparseon)Mengonfigurasi kompromi antara akurasi dan penyimpananSELECT hll_set_defaults(15, 5, -1, 1)
hll_print(hll)Mengembalikan informasi debug untuk nilai hllSELECT hll_print(hll_add_agg(1::hll_hashval))

Langkah berikutnya