Tampilan yang di-materialisasi (materialized views) melakukan pra-komputasi dan menyimpan hasil kueri sehingga AnalyticDB for MySQL dapat langsung menyajikan hasil tersebut tanpa harus menjalankan ulang operasi penggabungan tabel dan agregasi multi-tabel yang mahal pada setiap kueri. Topik ini menjelaskan cara membuat tampilan yang di-materialisasi, memilih jenis refresh, serta menangani error umum.
Prasyarat
Sebelum memulai, pastikan bahwa:
Versi kernel kluster adalah 3.1.3.4 atau lebih baru. Untuk memeriksa atau memperbarui versi, buka bagian Configuration Information pada halaman Cluster Information di AnalyticDB for MySQL console.
Akun database Anda memiliki semua izin yang diperlukan:
Izin CREATE pada tabel di database target
Izin SELECT pada semua kolom (atau kolom tertentu) dari setiap tabel dasar yang direferensikan oleh tampilan yang di-materialisasi
Untuk tampilan yang di-materialisasi dengan refresh otomatis, tambahan:
Izin untuk terhubung dari
'%'(alamat IP apa pun)Izin INSERT pada tampilan yang di-materialisasi atau semua tabel di dalam database-nya
Pilih jenis refresh
AnalyticDB for MySQL mendukung dua jenis refresh. Jenis refresh menentukan fitur SQL apa saja yang dapat digunakan dalam isi kueri dan bagaimana tampilan yang di-materialisasi tetap sinkron dengan tabel dasarnya.
Complete refresh | Fast (incremental) refresh | |
Cara kerja | Mengganti seluruh data dalam tampilan yang di-materialisasi | Hanya menerapkan perubahan sejak refresh terakhir |
Tabel dasar | Tabel internal, tabel eksternal, tampilan yang di-materialisasi yang sudah ada, dan view | Hanya tabel internal |
Dukungan SQL | Sintaks SELECT lengkap | Subset dari SELECT (lihat Incremental MV query constraints) |
Pemicu refresh | Auto-refresh terjadwal, auto-refresh saat tabel dasar di-overwrite, atau refresh manual | Hanya auto-refresh terjadwal (interval: 5 detik hingga 5 menit) |
Versi minimum | 3.1.3.4 | 3.1.9.0 (tabel tunggal); 3.2.1.0 (multi-tabel) |
Siapkan tabel dasar
Contoh dalam topik ini menggunakan dua tabel berikut. Buat kedua tabel ini sebelum menjalankan contoh tampilan yang di-materialisasi.
/*+ RC_DDL_ENGINE_REWRITE_XUANWUV2=false */ -- Set the table engine to XUANWU.
CREATE TABLE customer (
customer_id INT PRIMARY KEY,
customer_name VARCHAR(255),
is_vip Boolean
);
/*+ RC_DDL_ENGINE_REWRITE_XUANWUV2=false */ -- Set the table engine to XUANWU.
CREATE TABLE sales (
sale_id INT PRIMARY KEY,
product_id INT,
customer_id INT,
price DECIMAL(10, 2),
quantity INT,
sale_date TIMESTAMP
);Contoh tidak menentukan kelompok sumber daya. Tanpa kelompok sumber daya, AnalyticDB for MySQL menggunakan sumber daya komputasi cadangan dari kelompok sumber daya interaktif default untuk membuat dan merefresh tampilan yang di-materialisasi. Untuk menggunakan kelompok sumber daya job sebagai gantinya, lihat Use elastic resources.
Buat tampilan yang di-materialisasi dengan complete refresh
Tampilan yang di-materialisasi dengan complete refresh mendukung sintaks SELECT lengkap dan dapat mereferensikan tabel internal, tabel eksternal, tampilan yang di-materialisasi yang sudah ada, serta view.
Contoh berikut membuat tampilan yang di-materialisasi bernama join_mv yang menggabungkan customer dan sales, serta dikonfigurasi untuk refresh manual:
CREATE MATERIALIZED VIEW join_mv
REFRESH COMPLETE ON DEMAND
AS
SELECT
sale_id,
SUM(price * quantity) AS price
FROM customer
INNER JOIN (SELECT sale_id, customer_id, price, quantity FROM sales) sales
ON customer.customer_id = sales.customer_id
GROUP BY customer.customer_id;Untuk merefresh tampilan secara manual, jalankan:
REFRESH MATERIALIZED VIEW join_mv;Buat tampilan yang di-materialisasi fast (incremental)
Tampilan yang di-materialisasi fast hanya menerapkan perubahan sejak refresh terakhir, yang lebih efisien untuk dataset besar yang berubah secara inkremental. Konsekuensinya adalah dukungan fitur SQL yang lebih terbatas — isi kueri SELECT menentukan apakah refresh inkremental dapat diterapkan (lihat Incremental MV query constraints).
Persyaratan versi: 3.1.9.0 atau lebih baru (tabel tunggal), 3.2.1.0 atau lebih baru (multi-tabel).
Aktifkan binary logging
Refresh inkremental bergantung pada binary logging untuk melacak perubahan di tabel dasar. Aktifkan di tingkat kluster dan untuk setiap tabel dasar:
SET ADB_CONFIG BINLOG_ENABLE=true;
ALTER TABLE customer binlog=true;
ALTER TABLE sales binlog=true;Jika aktivasi binary logging gagal, lihat Can not create FAST materialized view.
Buat tampilan yang di-materialisasi fast tabel tunggal
Contoh berikut membuat tampilan yang di-materialisasi fast bernama sales_mv_incre pada tabel sales dengan interval auto-refresh 3 menit:
CREATE MATERIALIZED VIEW sales_mv_incre
REFRESH FAST NEXT now() + INTERVAL 3 minute
AS
SELECT
sale_id,
SUM(price * quantity) AS price
FROM sales
GROUP BY sale_id;Buat tampilan yang di-materialisasi fast multi-tabel
Pada kluster yang menjalankan V3.2.1.0 atau lebih baru, tampilan yang di-materialisasi fast dapat menggabungkan beberapa tabel. Contoh berikut menggabungkan customer dan sales:
CREATE MATERIALIZED VIEW join_mv_incre
REFRESH FAST NEXT now() + INTERVAL 3 minute
AS
SELECT
customer.customer_id,
SUM(sales.price) AS price
FROM customer
INNER JOIN (SELECT customer_id, price FROM sales) sales
ON customer.customer_id = sales.customer_id
GROUP BY customer.customer_id;Catatan
Jika tabel dasar mengalami operasi TRUNCATE atau INSERT OVERWRITE, atau terjadi anomali internal yang dapat memengaruhi kebenaran data, tampilan yang di-materialisasi inkremental secara otomatis beralih ke refresh lengkap satu kali. Setelah refresh lengkap berhasil, refresh berikutnya secara otomatis kembali ke mode inkremental.
Untuk sintaks lengkap CREATE MATERIALIZED VIEW, lihat CREATE MATERIALIZED VIEW.
Monitor progres pembuatan
Pernyataan CREATE MATERIALIZED VIEW dapat memakan waktu karena mencakup pemuatan data awal. Jalankan kueri berikut untuk menampilkan daftar tampilan yang di-materialisasi yang sedang dibuat:
SHOW PROCESSLIST WHERE info LIKE '%CREATE MATERIALIZED VIEW%';Setiap baris merepresentasikan tampilan yang di-materialisasi yang sedang diproses. Kolom User menunjukkan akun database, State menunjukkan status saat ini, dan Info berisi pernyataan CREATE lengkap. Untuk definisi kolom, lihat SHOW PROCESSLIST.
Ketika SHOW PROCESSLIST tidak mengembalikan baris apa pun, tampilan yang di-materialisasi telah berhasil dibuat, termasuk skema dan data awalnya.
Gunakan sumber daya elastis untuk membuat atau merefresh tampilan yang di-materialisasi
Secara default, AnalyticDB for MySQL menggunakan sumber daya komputasi cadangan dari kelompok sumber daya interaktif default (user_default) untuk membuat dan merefresh tampilan yang di-materialisasi. Untuk menghindari persaingan dengan beban kerja interaktif, gunakan kelompok sumber daya job sebagai gantinya.
Kapan menggunakan sumber daya elastis:
Anda ingin mengisolasi pembuatan dan refresh tampilan yang di-materialisasi dari kueri interaktif.
Anda ingin menghindari pembelian sumber daya khusus di muka.
Konsekuensi: Kelompok sumber daya job menyediakan sumber daya komputasi sesuai permintaan, yang menambahkan overhead startup beberapa detik hingga menit sebelum setiap refresh dibandingkan dengan kelompok sumber daya interaktif.
Persyaratan kluster:
Enterprise Edition, Basic Edition, atau Data Lakehouse Edition
V3.1.9.3 atau lebih baru
Tentukan kelompok sumber daya job menggunakan MV_PROPERTIES. Contoh berikut membuat tampilan yang di-materialisasi menggunakan kelompok sumber daya job my_job_rg dengan prioritas tinggi dan refresh harian:
CREATE MATERIALIZED VIEW job_mv
MV_PROPERTIES='{
"mv_resource_group": "my_job_rg",
"mv_refresh_hints": {"query_priority": "HIGH"}
}'
REFRESH COMPLETE ON DEMAND
START WITH now()
NEXT now() + INTERVAL 1 DAY
AS
SELECT * FROM customer;Untuk membatasi maksimum sumber daya yang digunakan selama refresh, tambahkan "elastic_job_max_acu": "<value>" ke dalam mv_refresh_hints. Untuk daftar lengkap opsi mv_properties, lihat mv_properties.
Mekanisme pemicu refresh
Tampilan yang di-materialisasi mencerminkan data pada saat refresh terakhir, bukan keadaan terkini dari tabel dasar. Pilih pemicu refresh berdasarkan seberapa mutakhir data yang dibutuhkan:
Auto-refresh terjadwal: Refresh pada interval tetap (misalnya, setiap 3 menit, setiap hari). Didukung oleh refresh lengkap maupun fast.
Auto-refresh saat tabel dasar di-overwrite: Memicu refresh ketika tabel dasar di-overwrite. Hanya didukung oleh refresh lengkap.
Refresh manual: Jalankan
REFRESH MATERIALIZED VIEW <view_name>;saat diperlukan. Hanya didukung oleh refresh lengkap.
Untuk detail kebijakan refresh dan sintaks refresh manual, lihat Refresh materialized views.
Incremental MV query constraints
Isi kueri SELECT pada tampilan yang di-materialisasi fast memiliki batasan yang tidak berlaku untuk tampilan dengan refresh lengkap. Batasan paling krusial adalah:
Hanya INNER JOIN yang didukung. Kolom join harus merupakan kolom asli dari tabel dasar, memiliki tipe data identik, dan diindeks. Anda dapat menggabungkan hingga lima tabel dasar.
Jika suatu batasan menghalangi kasus penggunaan Anda, gunakan tampilan yang di-materialisasi dengan refresh lengkap sebagai gantinya — tampilan ini mendukung sintaks SELECT lengkap tanpa batasan join.
Tabel berikut mencantumkan semua fitur SQL yang tidak didukung.
Fitur | Didukung? | Catatan |
INNER JOIN (multi-tabel) | Ya (V3.2.1.0+) | Hingga 5 tabel; kolom join harus diindeks dan memiliki tipe data yang sesuai |
UNION ALL | Ya (V3.2.5.0+) | Memerlukan struktur kueri khusus (lihat di bawah) |
COUNT, SUM, MAX, MIN, AVG, APPROX_DISTINCT, COUNT(DISTINCT) | Ya | Fungsi agregat lainnya tidak didukung |
AVG dengan DECIMAL | Tidak | Gunakan tipe numerik lain |
COUNT(DISTINCT) dengan non-INTEGER | Tidak | Hanya mendukung tipe INTEGER |
Window functions | Tidak | — |
HAVING clause | Tidak | — |
ORDER BY clause | Tidak | — |
Ekspresi nondeterministik (NOW(), RAND()) | Tidak | — |
UNION, EXCEPT, INTERSECT | Tidak | UNION ALL didukung mulai V3.2.5.0 |
Tabel XUANWU_V2 sebagai tabel dasar | Tidak (sebelum V3.2.6.0) | XUANWU_V2 mendukung binary logging mulai V3.2.6.0 |
Tabel terpartisi sebagai tabel dasar | Tidak (sebelum V3.2.3.0) | — |
INSERT OVERWRITE atau TRUNCATE pada tabel dasar | Tidak (sebelum V3.2.3.1) | Mengembalikan error |
MAX(), MIN(), APPROX_DISTINCT(), COUNT(DISTINCT) dengan DELETE/UPDATE/REPLACE/INSERT ON DUPLICATE KEY UPDATE | Tidak | Tabel dasar hanya mendukung INSERT |
Fast MV sebagai tabel dasar (nested fast MVs) | Ya (V3.2.5.0+) | Memerlukan binary logging diaktifkan pada tampilan yang di-materialisasi |
Untuk menggabungkan lebih dari lima tabel dalam tampilan yang di-materialisasi fast, hubungi dukungan teknis.
Aturan kolom SELECT
Kolom dalam daftar SELECT harus mengikuti aturan berikut:
Dengan GROUP BY dan fungsi agregat: Sertakan semua kolom GROUP BY dalam daftar SELECT.
Dengan fungsi agregat tanpa GROUP BY: Daftar SELECT hanya boleh berisi kolom agregat, atau konstanta dan kolom agregat.
Tanpa agregasi: Sertakan semua kolom kunci primer dari tabel dasar.
Kueri UNION ALL: Setiap cabang harus menghasilkan kolom bernama
union_all_markerdengan nilai konstan berbeda per cabang. Sertakan semua kolom kunci primer tabel dasar. Kunci primer tampilan yang di-materialisasi harus mencakup kolom kunci primer tabel dasar danunion_all_marker.CREATE MATERIALIZED VIEW demo_union_all_mv (PRIMARY KEY(id, union_all_marker)) REFRESH FAST NEXT now() + INTERVAL 5 minute AS SELECT customer_id AS id, "customer" AS union_all_marker FROM customer UNION ALL SELECT sale_id AS id, "sales" AS union_all_marker FROM sales;Kolom ekspresi: Semua kolom ekspresi dalam daftar SELECT harus memiliki alias, misalnya
SUM(price) AS total_price.
Batasan
Batasan umum
Batasan berikut berlaku untuk semua tampilan yang di-materialisasi.
Anda tidak dapat menjalankan INSERT, DELETE, atau UPDATE pada tampilan yang di-materialisasi.
Anda tidak dapat menghapus atau mengganti nama tabel dasar atau kolomnya selama tampilan yang di-materialisasi masih mereferensikannya. Hapus tampilan yang di-materialisasi terlebih dahulu, lalu ubah tabel dasar.
Maksimum tampilan yang di-materialisasi per kluster:
V3.1.4.7 atau lebih baru: 64
Lebih awal dari V3.1.4.7: 8
Untuk menaikkan kuota, hubungi dukungan teknis.
Batasan pada tampilan yang di-materialisasi dengan complete refresh
Ketika Anda menambah atau menghapus node cadangan, job asinkron dinonaktifkan. Karena complete refresh merupakan job asinkron, refresh ini tidak dapat dijalankan selama penskalaan node. Fast refresh tidak terpengaruh.
Batasan pada tampilan yang di-materialisasi fast (incremental)
Lihat Incremental MV query constraints untuk daftar lengkap pembatasan SQL.
Pemicu refresh: Hanya auto-refresh terjadwal yang didukung. Interval harus antara 5 detik hingga 5 menit.
Batasan penggabungan multi-tabel dalam tampilan yang di-materialisasi inkremental:
Hingga lima tabel dasar dapat digabungkan.
Untuk menyesuaikan batasan ini, untuk menghubungi dukungan teknis berdasarkan spesifikasi kluster Anda.
Hanya INNER JOIN yang didukung.
Kolom join harus merupakan kolom asli dari tabel dasar, memiliki tipe data identik, dan diindeks.
FAQ
Bagaimana cara menyimpan hanya data satu tahun terakhir dalam tampilan yang di-materialisasi?
Gunakan kolom tanggal sebagai kunci partisi (PARTITION BY) dan atur nilai LIFECYCLE untuk membatasi jumlah partisi yang disimpan. Untuk tampilan yang dipartisi per hari, atur LIFECYCLE 365 untuk menyimpan 365 partisi terbaru (satu tahun).
Contoh: tabel sales menerima catatan baru setiap hari, dipartisi berdasarkan sale_date:
CREATE MATERIALIZED VIEW sales_mv_lifecycle
PARTITION BY VALUE(DATE_FORMAT(sale_date, '%Y%m%d')) LIFECYCLE 365
REFRESH FAST NEXT now() + INTERVAL 100 second
AS
SELECT
sale_date,
SUM(price * quantity) AS price
FROM sales
GROUP BY sale_date;Pemecahan Masalah
Kesalahan eksekusi kueri: Tidak dapat membuat tampilan FAST yang di-materialisasi, karena *demotable* tidak mendukung pengambilan data inkremental
Binary logging tidak diaktifkan untuk tabel dasar demotable. Aktifkan dengan:
ALTER TABLE demotable binlog=true;Jika Anda melihat XUANWU_V2 engine not support ALTER_BINLOG_ENABLE now, tabel dasar menggunakan mesin XUANWU_V2 dan kluster menjalankan versi kernel sebelum V3.2.6.0. XUANWU_V2 mendukung binary logging mulai versi kernel V3.2.6.0. Upgrade kluster ke V3.2.6.0 atau lebih baru, lalu jalankan kembali ALTER TABLE demotable binlog=true; untuk mengaktifkan binary logging pada tabel dasar.
Error eksekusi kueri: PRIMARY KEY *id* must output to MV
Tampilan yang di-materialisasi fast Anda menggunakan kueri non-agregat tanpa GROUP BY. Dalam kasus ini, daftar SELECT harus menyertakan semua kolom kunci primer dari tabel dasar.
Salah (tidak menyertakan sale_id, yang merupakan kunci primer dari sales):
CREATE MATERIALIZED VIEW wrong_example1
REFRESH FAST ON DEMAND
NEXT now() + interval 200 second
AS
SELECT product_id, price
FROM sales;Tambahkan kolom kunci primer:
CREATE MATERIALIZED VIEW correct_example1
REFRESH FAST ON DEMAND
NEXT now() + interval 200 second
AS
SELECT sale_id, product_id, price
FROM sales;Error eksekusi kueri: MV PRIMARY KEY must be equal to base table PRIMARY KEY
Tampilan yang di-materialisasi fast Anda menggunakan kueri non-agregat tanpa GROUP BY, dan definisi kunci primer tampilan mencakup kolom yang bukan bagian dari kunci primer tabel dasar.
Salah (product_id bukan kolom kunci primer dari sales):
CREATE MATERIALIZED VIEW wrong_example2
(PRIMARY KEY(sale_id, product_id))
REFRESH FAST ON DEMAND
NEXT now() + interval 200 second
AS
SELECT sale_id, product_id, price
FROM sales;Hapus kolom non-kunci-primer dari definisi kunci primer:
CREATE MATERIALIZED VIEW correct_example2
(PRIMARY KEY(sale_id))
REFRESH FAST ON DEMAND
NEXT now() + interval 200 second
AS
SELECT sale_id, product_id, price
FROM sales;Error eksekusi kueri: FAST materialized view must define PRIMARY KEY
Error ini memiliki dua kemungkinan penyebab:
Tidak ada kunci primer yang valid didefinisikan. Perbarui definisi tampilan yang di-materialisasi agar memenuhi aturan berikut:
Kueri agregat bergrup (dengan GROUP BY): kunci primer harus berupa kolom GROUP BY (misalnya, jika
GROUP BY a, b, aturPRIMARY KEY(a, b)).Kueri agregat tidak bergrup (tanpa GROUP BY): kunci primer harus berupa konstanta.
Kueri non-agregat: kunci primer harus persis sama dengan kunci primer tabel dasar (misalnya, jika tabel dasar memiliki
PRIMARY KEY(sale_id, sale_date), tampilan juga harus memilikiPRIMARY KEY(sale_id, sale_date)).
Fungsi diterapkan pada kolom kunci primer. Hapus fungsi dari kolom kunci primer dalam kueri.
Error eksekusi kueri: The join graph is not supported
Kolom join memiliki tipe data yang tidak sesuai. Misalnya, jika customer.id dan sales.id memiliki tipe berbeda, join akan gagal. Samakan tipe datanya dengan:
ALTER TABLE tablename MODIFY COLUMN columnname newtype;Untuk informasi lebih lanjut, lihat Change the data type of a column.
Kesalahan eksekusi kueri: Tidak dapat menggunakan index join untuk menyegarkan fast MV ini
Kolom join tidak memiliki indeks. Tambahkan indeks pada setiap kolom join:
ALTER TABLE tablename ADD KEY idx_name(columnname);Untuk informasi lebih lanjut, lihat Create an index.
Error eksekusi kueri: Query exceeded reserved memory limit
Kueri melebihi batas memori per node. Gunakan fitur SQL diagnostics untuk mengidentifikasi tahapan dan operator berkonsumsi memori tinggi (Aggregation, TopN, Window, dan Join adalah penyebab umum), lalu optimalkan operator tersebut. Lihat juga Memory metrics dan Use stage and task details to analyze queries.
Langkah Berikutnya
Materialized views — konsep, kasus penggunaan, dan pembaruan fitur
CREATE MATERIALIZED VIEW — referensi sintaks lengkap
Refresh materialized views — kebijakan refresh, pemicu, dan refresh manual
Manage materialized views — kueri definisi, riwayat refresh, daftar, dan hapus
Query data from a materialized view — sintaks dan contoh kueri