All Products
Search
Document Center

AnalyticDB:Buat tampilan yang di-materialisasi

Last Updated:Jul 10, 2026

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.

Lihat contoh hasil

Contoh output:

+-------+-------------------+-------+--------------------+-------+-------------------+----+---------+-------------------------------+
|Id     |ProcessId          |User   |Host                |DB     |Command            |Time|State    |Info                           |
+-------+-------------------+-------+--------------------+-------+-------------------+----+---------+-------------------------------+
|31801  |20250127144727...  |wenjun |21.17.xx.xx:49534   |demo1  |INSERT_FROM_SELECT |2   |RUNNING  |CREATE MATERIALIZED VIEW join_mv|
|       |                   |       |                    |       |                   |    |         |REFRESH COMPLETE ON DEMAND     |
|       |                   |       |                    |       |                   |    |         |AS ...                         |
+-------+-------------------+-------+--------------------+-------+-------------------+----+---------+-------------------------------+

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:

Penting

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.

    Lihat contoh

    Contoh benar (semua kolom GROUP BY disertakan):

    CREATE MATERIALIZED VIEW demo_mv1
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT
      sale_id,    -- kolom GROUP BY
      sale_date,  -- kolom GROUP BY
      max(quantity) AS max,  -- kolom ekspresi harus memiliki alias
      sum(price) AS sum
    FROM sales
    GROUP BY sale_id, sale_date;

    Salah (kolom GROUP BY sale_date tidak disertakan):

    CREATE MATERIALIZED VIEW false_mv1
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT
      sale_id,
      max(quantity) AS max,
      sum(price) AS sum
    FROM sales
    GROUP BY sale_id, sale_date;  -- sale_date ada di GROUP BY tetapi tidak di SELECT
  • Dengan fungsi agregat tanpa GROUP BY: Daftar SELECT hanya boleh berisi kolom agregat, atau konstanta dan kolom agregat.

    Lihat contoh

    -- Hanya kolom agregat
    CREATE MATERIALIZED VIEW demo_mv2
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT
      max(quantity) AS max,
      sum(price) AS sum
    FROM sales;
    
    -- Konstanta ditambah kolom agregat (konstanta menjadi kunci primer)
    CREATE MATERIALIZED VIEW demo_mv3
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT
      1 AS pk,
      max(quantity) AS max,
      sum(price) AS sum
    FROM sales;
  • Tanpa agregasi: Sertakan semua kolom kunci primer dari tabel dasar.

    Lihat contoh

    -- Kunci primer tunggal
    CREATE MATERIALIZED VIEW demo_mv4
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT
      sale_id,   -- kolom kunci primer dari tabel dasar sales
      quantity
    FROM sales;
    
    -- Kunci primer gabungan: PRIMARY KEY(sale_id, sale_date)
    CREATE MATERIALIZED VIEW demo_mv5
    REFRESH FAST ON DEMAND
     NEXT now() + INTERVAL 3 minute
    AS
    SELECT
      sale_id,    -- kolom kunci primer pertama
      sale_date,  -- kolom kunci primer kedua
      quantity
    FROM sales1;
  • Kueri UNION ALL: Setiap cabang harus menghasilkan kolom bernama union_all_marker dengan 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 dan union_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, atur PRIMARY 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 memiliki PRIMARY 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