AnalyticDB for MySQL menyediakan empat fungsi bawaan untuk analisis funnel dan retensi: window_funnel, retention, retention_range_count, dan retention_range_sum. Gunakan fungsi-fungsi ini untuk mengukur laju konversi di berbagai langkah perjalanan pengguna dan melacak jumlah pengguna yang kembali dari waktu ke waktu.
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
Kluster AnalyticDB for MySQL yang menjalankan versi minor 3.1.6.0 atau lebih baru
Untuk melihat dan memperbarui versi minor, buka bagian Configuration Information pada halaman Cluster Information di AnalyticDB for MySQL console.
Latar Belakang
Analisis funnel mengukur pergerakan pengguna melalui urutan langkah yang telah ditentukan—misalnya, dari menelusuri produk hingga menyelesaikan pembelian. Pada setiap langkah, sebagian pengguna keluar; laju konversi menunjukkan proporsi pengguna yang berhasil melewati langkah tersebut. Teknik ini banyak digunakan dalam analisis traffic dan analisis konversi tujuan produk.
AnalyticDB for MySQL mendukung fungsi-fungsi berikut:
| Function | Purpose |
|---|---|
window_funnel | Menghitung sejauh mana pengguna maju melalui urutan event yang telah ditentukan dalam jendela waktu geser |
retention | Memeriksa apakah setiap pengguna memenuhi serangkaian kondisi berbasis tanggal, mengembalikan array biner |
retention_range_count | Mencatat status retensi per pengguna di interval tertentu, mengembalikan array dua dimensi |
retention_range_sum | Mengagregasi output retention_range_count dari semua pengguna untuk menghitung laju retensi harian |
Set data uji
Contoh dalam topik ini menggunakan User Behavior Data from Taobao for Recommendation dari Tianchi Lab. Set data berisi empat jenis perilaku:
| Behavior | Description |
|---|---|
pv | Tampilan halaman produk (dihitung sebagai satu klik) |
buy | Pembelian |
cart | Tambah ke keranjang belanja |
fav | Tambah ke favorit |
Untuk memuat set data ke AnalyticDB for MySQL, unggah ke Object Storage Service (OSS), lalu impor menggunakan tabel eksternal OSS.
Unggah set data ke OSS. Untuk informasi selengkapnya, lihat Upload objects.
Buat tabel eksternal OSS.
CREATE TABLE `user_behavior_oss` ( `user_id` string, `item_id` string, `cate_id` string, `event` string, `ts` bigint ) ENGINE = 'oss' TABLE_PROPERTIES = '{ "endpoint":"oss-cn-zhangjiakou.aliyuncs.com", "accessid":"******", "accesskey":"*******", "url":"oss://<bucket-name>/user_behavior/", "delimiter":"," }'Untuk informasi selengkapnya, lihat OSS external table syntax.
Buat tabel uji di AnalyticDB for MySQL.
CREATE TABLE user_behavior( uid string, event string, ts string )Impor data dari tabel eksternal OSS.
SUBMIT JOB INSERT OVERWRITE user_behavior SELECT user_id, event, ts FROM user_behavior_oss;
window_funnel
window_funnel mencari riwayat event pengguna untuk urutan event tertentu dalam jendela waktu geser. Fungsi ini mengembalikan panjang awalan paling panjang dari urutan tersebut yang cocok.
Cara kerja
Fungsi ini memproses event setiap pengguna secara kronologis:
Fungsi memindai event untuk menemukan kemunculan pertama dari kondisi awal dalam urutan Anda. Saat ditemukan, jendela geser dimulai.
Selanjutnya, fungsi mencari setiap kondisi berikutnya secara berurutan dalam jendela tersebut. Setiap kecocokan meningkatkan penghitung sebesar satu.
Jika urutan terputus atau jendela berakhir sebelum semua kondisi cocok, penghitung berhenti. Fungsi mengembalikan nilai penghitung tertinggi yang dicapai.
Contoh:
Daftar event
[c1, c2, c3], data pengguna[c1, c2, c3, c4]→ mengembalikan3(urutan lengkap cocok)Daftar event
[c1, c2, c3], data pengguna[c4, c3, c2, c1]→ mengembalikan1(hanya c1 yang cocok dari awal)Daftar event
[c1, c2, c3], data pengguna[c4, c3]→ mengembalikan0(kondisi pertama tidak pernah cocok)
Sintaks
window_funnel(window, mode, timestamp, cond1, cond2, ..., condN)Parameter
| Parameter | Type | Description |
|---|---|---|
window | Integer | Ukuran jendela waktu geser, dalam satuan yang sama dengan kolom timestamp |
mode | String | Mode kerja. Tetapkan ke "default" |
timestamp | BIGINT | Kolom timestamp. Harus bertipe data BIGINT. Jika kolom timestamp Anda bukan BIGINT, gunakan TIMESTAMPDIFF untuk mengonversinya. Contoh: TIMESTAMPDIFF('second', '2017-11-25 00:00:00.000', ts) |
cond1, ..., condN | Boolean | Kondisi event yang mendefinisikan langkah funnel, dievaluasi secara berurutan |
Contoh
Contoh berikut menganalisis jalur konversi — telusuri → tambah ke favorit → tambah ke keranjang → beli — dari 2017-11-25 00:00:00 hingga 2017-11-26 00:00:00. Jendela waktu geser adalah 30 menit (1.800 detik), dan timestamp dalam format Unix (1511539200 hingga 1511625600).
Kueri dijalankan dalam dua tahap: kueri dalam menghitung kedalaman funnel per pengguna, dan kueri luar menghitung jumlah pengguna yang mencapai setiap kedalaman.
SELECT
funnel,
count(1)
FROM (
SELECT
uid,
window_funnel(
cast(1800 as integer), -- Jendela geser 30 menit
"default",
ts,
event = 'pv', -- Langkah 1: Telusuri
event = 'fav', -- Langkah 2: Tambah ke favorit
event = 'cart', -- Langkah 3: Tambah ke keranjang
event = 'buy' -- Langkah 4: Beli
) AS funnel
FROM user_behavior
WHERE ts > 1511539200
AND ts < 1511625600
GROUP BY uid
)
GROUP BY funnel;Hasil contoh:
+--------+----------+
| funnel | count(1) |
+--------+----------+
| 0 | 19687 |
| 1 | 596104 |
| 2 | 78458 |
| 3 | 11640 |
| 4 | 746 |
+--------+----------+
5 rows in set (0.64 sec)Nilai 4 berarti pengguna menyelesaikan keempat langkah. Nilai 1 berarti hanya langkah pertama (telusuri) yang cocok.
retention
retention memeriksa apakah pengguna memenuhi serangkaian kondisi — biasanya satu kondisi per hari — dan mengembalikan array UINT8 di mana setiap elemen bernilai 1 (kondisi terpenuhi) atau 0 (kondisi tidak terpenuhi).
Sintaks
retention(cond1, cond2, ..., cond32)Parameter
| Parameter | Type | Description |
|---|---|---|
cond1, ..., cond32 | UINT8 | Kondisi yang akan dievaluasi, maksimal 32. Mengembalikan 1 jika kondisi terpenuhi, 0 jika tidak |
Contoh
Contoh berikut mengukur retensi 7 hari mulai 25 November 2017. sum(r[1]) menghitung pengguna yang aktif pada hari ke-1; sum(r[2]) hingga sum(r[7]) menghitung jumlah pengguna yang kembali pada setiap hari berikutnya.
Tahap 1 — hitung array retensi per pengguna:
SELECT
uid,
retention(
ds = '2017-11-25' AND event = 'pv', -- Hari 1: aktif (garis dasar)
ds = '2017-11-25', -- Pemeriksaan retensi hari 1
ds = '2017-11-26', -- Hari 2
ds = '2017-11-27', -- Hari 3
ds = '2017-11-28', -- Hari 4
ds = '2017-11-29', -- Hari 5
ds = '2017-11-30' -- Hari 6
) AS r
FROM user_behavior_date
GROUP BY uidTahap 2 — agregasi lintas semua pengguna:
SELECT
sum(r[1]), -- Pengguna aktif pada hari 1
sum(r[2]), -- Dipertahankan pada hari 1
sum(r[3]), -- Dipertahankan pada hari 2
sum(r[4]), -- Dipertahankan pada hari 3
sum(r[5]), -- Dipertahankan pada hari 4
sum(r[6]), -- Dipertahankan pada hari 5
sum(r[7]) -- Dipertahankan pada hari 6
FROM (
SELECT
retention(
ds = '2017-11-25' AND event = 'pv',
ds = '2017-11-25',
ds = '2017-11-26',
ds = '2017-11-27',
ds = '2017-11-28',
ds = '2017-11-29',
ds = '2017-11-30'
) AS r
FROM user_behavior_date
GROUP BY uid
);Hasil contoh:
+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
| sum(r[1]) | sum(r[2]) | sum(r[3]) | sum(r[4]) | sum(r[5]) | sum(r[6]) | sum(r[7]) |
+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
| 686953 | 686953 | 544367 | 529979 | 523516 | 524530 | 528105 |
+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
1 row in set (2.96 sec)retention_range_count dan retention_range_sum
retention_range_count dan retention_range_sum dirancang untuk analisis pertumbuhan pengguna. Fungsi ini mendukung interval retensi fleksibel dan menghasilkan output yang sesuai untuk visualisasi.
retention_range_countmenghitung status retensi per pengguna di interval hari tertentu, mengembalikan array dua dimensi.retention_range_summengambil outputretention_range_countdan mengagregasinya dari semua pengguna untuk menghasilkan laju retensi harian.
Sintaks
-- Retensi per pengguna
retention_range_count(is_first, is_active, dt, intervals, outputFormat)
-- Agregasi lintas pengguna
retention_range_sum(retention_range_count_result)Parameter
retention_range_count:
| Parameter | Type | Description |
|---|---|---|
is_first | Boolean | Apakah baris ini cocok dengan event aktivasi. true = ini adalah perilaku awal |
is_active | Boolean | Apakah baris ini cocok dengan event retensi. true = ini dihitung sebagai perilaku yang dipertahankan |
dt | Date | Tanggal event, dalam format date (misalnya, 2022-05-01) |
intervals[] | Array | Interval retensi yang dilacak (misalnya, array(1, 2) untuk retensi hari ke-1 dan hari ke-2). Maksimal 15 interval didukung |
outputFormat | String | Format nilai kembali. Nilai valid: normal (default) atau expand |
Nilai outputFormat:
| Value | Output format |
|---|---|
normal (default) | [[d1(tanggal mulai), 1, 0, ...], [d2(tanggal mulai), 1, 0, ...], ...] — setiap baris berupa [tanggal mulai, flag_interval_1, flag_interval_2, ...], di mana 1 = dipertahankan dan 0 = tidak dipertahankan |
expand | [[d1(tanggal mulai), d1+1(tanggal retensi)], [d1, d1+2], [d2, d2+1], [d2, d2+3]] |
retention_range_sum:
| Parameter | Description |
|---|---|
retention_range_count_result | Array dua dimensi output dari retention_range_count |
Contoh
Contoh berikut menghitung retensi hari ke-1 dan hari ke-2 untuk pengguna yang login pada 1–2 Mei 2022, berdasarkan aktivitas dari 1–4 Mei 2022. Event aktivasi adalah login dan event retensi adalah pay.
Langkah 1. Buat tabel uji dan masukkan data.
CREATE TABLE event(uid string, event string, ds date);INSERT INTO event VALUES
("user1", "pay", "2022-05-01"),
("user1", "login", "2022-05-01"),
("user1", "pay", "2022-05-02"),
("user1", "login", "2022-05-02"),
("user2", "login", "2022-05-01"),
("user3", "login", "2022-05-02"),
("user3", "pay", "2022-05-03"),
("user3", "pay", "2022-05-04");Data contoh:
+-------+-------+------------+
| uid | event | ds |
+-------+-------+------------+
| user1 | login | 2022-05-01 |
| user1 | pay | 2022-05-01 |
| user1 | login | 2022-05-02 |
| user1 | pay | 2022-05-02 |
| user2 | login | 2022-05-01 |
| user3 | login | 2022-05-02 |
| user3 | pay | 2022-05-03 |
| user3 | pay | 2022-05-04 |
+-------+-------+------------+Langkah 2. Hitung status retensi per pengguna.
SELECT
uid,
r
FROM (
SELECT
uid,
retention_range_count(
event = 'login', -- Event aktivasi
event = 'pay', -- Event retensi
ds,
array(1, 2) -- Lacak retensi hari ke-1 dan hari ke-2
) AS r
FROM event
GROUP BY uid
) AS t
ORDER BY uid;Hasil contoh:
+-------+-----------------------------+
| uid | r |
+-------+-----------------------------+
| user1 | [[738642,0,0],[738641,1,0]] |
| user2 | [[738641,0,0]] |
| user3 | [[738642,1,1]] |
+-------+-----------------------------+Setiap array berisi [tanggal_mulai_sebagai_hari, retensi_hari1, retensi_hari2]. Misalnya, user3 login pada 2 Mei (hari ke-738642) dan melakukan pembayaran pada 3 Mei (hari ke-1) serta 4 Mei (hari ke-2).
Langkah 3. Agregasi untuk mendapatkan laju retensi harian lintas semua pengguna.
SELECT
from_days(u[1]) AS ds,
u[3] / u[2] AS retention_d1,
u[4] / u[2] AS retention_d2
FROM (
SELECT retention_range_sum(r) AS r
FROM (
SELECT
uid,
retention_range_count(
event = 'login',
event = 'pay',
ds,
array(1, 2)
) AS r
FROM event
GROUP BY uid
) AS t
ORDER BY uid
) AS r,
unnest(r.r) AS t(u);Hasil contoh:
+------------+--------------+--------------+
| ds | retention_d1 | retention_d2 |
+------------+--------------+--------------+
| 2022-05-02 | 0.5 | 0.5 |
| 2022-05-01 | 0.5 | 0.0 |
+------------+--------------+--------------+Pada 1 Mei, dua pengguna login (user1 dan user2). Hanya user1 yang membayar pada 2 Mei (hari ke-1 setelah aktivasi), sehingga retensi hari ke-1 untuk 1 Mei adalah 0,5. Tidak ada pengguna yang membayar pada 3 Mei (hari ke-2 setelah aktivasi), sehingga retensi hari ke-2 untuk 1 Mei adalah 0,0. Pada 2 Mei, dua pengguna login (user1 dan user3). Keduanya membayar dalam dua hari berikutnya, sehingga retensi hari ke-1 dan hari ke-2 keduanya 0,5 untuk pengguna yang diaktifkan pada 2 Mei.