All Products
Search
Document Center

AnalyticDB:Penulisan ulang kueri tampilan yang di-materialisasi

Last Updated:Sep 17, 2026

Fitur query rewrite memungkinkan AnalyticDB for MySQL mengarahkan kueri secara otomatis ke materialized views—tanpa perubahan apa pun pada SQL Anda. Ketika sebuah kueri sesuai dengan materialized view, mesin membaca hasil yang telah diproses sebelumnya alih-alih melakukan pemindaian pada tabel dasar, sehingga dapat mengurangi latensi kueri secara signifikan.

Prasyarat

  • Kluster AnalyticDB for MySQL menjalankan versi V3.1.4.0 atau lebih baru.

    Catatan
    • Untuk memeriksa versi minor kluster Data Lakehouse Edition, jalankan SELECT adb_version();. Untuk melakukan peningkatan versi minor, hubungi dukungan teknis.

    • Untuk melihat dan meningkatkan versi minor kluster Data Warehouse Edition, lihat Upgrade minor version.

  • Untuk menggunakan materialized views, izin berikut diperlukan:

    • Izin CREATE pada database tempat materialized view berada.

    • Izin SELECT pada kolom yang relevan, atau pada seluruh tabel, dari semua tabel dasar materialized view.

    • Untuk membuat materialized view yang direfresh secara otomatis, dua izin tambahan berikut juga diperlukan:

      • Izin untuk terhubung ke AnalyticDB for MySQL dari alamat IP mana pun (yaitu, '%').

      • Izin INSERT pada materialized view atau pada semua tabel dalam database tempat materialized view berada. Jika tidak, data dalam materialized view tidak dapat direfresh.

Cara kerja

AnalyticDB for MySQL membandingkan setiap kueri masuk terhadap semua materialized views yang telah diaktifkan fitur query rewrite-nya. Jika ditemukan kecocokan, mesin menulis ulang kueri tersebut agar membaca dari materialized view alih-alih dari tabel dasar. Dua strategi pencocokan digunakan, diterapkan dalam urutan berikut:

  • Exact match rewrite — ketika struktur kueri identik dengan definisi materialized view. Ini adalah strategi yang lebih sederhana dengan batasan lebih sedikit.

  • Advanced query rewrite — ketika strukturnya berbeda. Mesin menerapkan aturan penulisan ulang (FILTER, JOIN, AGGREGATION, AGGREGATION ROLLUP, SUBQUERIES, QUERY PARTIAL, UNION) untuk menentukan apakah materialized view berisi data yang cukup untuk menjawab kueri atau sebagiannya. Subkueri yang berbeda dalam satu pernyataan yang sama dapat sesuai dengan materialized views yang berbeda.

Semua penulisan ulang kueri beroperasi pada level STALE_TOLERATED: mesin menulis ulang kueri bahkan jika materialized view berisi data lama yang belum disinkronkan dari tabel dasar. Hal ini memaksimalkan cakupan penulisan ulang, tetapi berarti hasilnya mungkin tidak mencerminkan data terbaru yang dimasukkan atau diperbarui. Refresh materialized views Anda sebelum menjalankan kueri yang sensitif terhadap latensi. Untuk detail selengkapnya, lihat Configure full refresh for materialized views.

Aktifkan query rewrite

Aktifkan query rewrite dengan salah satu dari dua cara berikut:

Nonaktifkan query rewrite

Nonaktifkan query rewrite dengan salah satu dari dua cara berikut:

  • Untuk materialized view tertentu:

    ALTER MATERIALIZED VIEW <mv_name> DISABLE QUERY REWRITE;
  • Untuk kueri tertentu, tambahkan petunjuk sebelum pernyataan SELECT:

    /*+MV_QUERY_REWRITE_ENABLED=false*/
    SELECT ...

Verifikasi bahwa query rewrite aktif

Setelah mengaktifkan query rewrite, gunakan EXPLAIN untuk memastikan mesin membaca dari materialized view.

Contoh

  1. Buat materialized view dengan query rewrite diaktifkan.

    CREATE MATERIALIZED VIEW adb_mv
    REFRESH START WITH now() + interval 1 day
    ENABLE QUERY REWRITE
    AS
    SELECT course_id, course_name, max(course_grade) AS max_grade FROM tb_courses;
  2. Setelah mengaktifkan query rewrite, jalankan EXPLAIN pada kueri tersebut.

    EXPLAIN SELECT course_id, course_name, max(course_grade) AS max_grade FROM tb_courses;
  3. Periksa rencana eksekusi. Saat query rewrite aktif, baris TableScan menampilkan nama materialized view (adb_mv), bukan tabel dasar (tb_courses).

    +---------------+
    | Plan Summary  |
    +---------------+
     1- Output[ Query plan ] {Est rowCount: 1.0}
     2    -> Exchange[GATHER] {Est rowCount: 1.0}
     3        - TableScan {table: adb_mv, Est rowCount: 1.0}

    Jika rencana masih menampilkan TableScan {table: tb_courses, ...}, query rewrite tidak diaktifkan. Periksa bagian Troubleshooting.

Rentang penulisan ulang

Contoh berikut menunjukkan setiap aturan penulisan ulang yang didukung oleh metode advanced query rewrite. Semua contoh menggunakan empat tabel yang sama:

CREATE TABLE part (
  partkey INTEGER NOT NULL,
  name VARCHAR(55) NOT NULL,
  type VARCHAR(25) NOT NULL
);

CREATE TABLE lineitem (
  orderkey BIGINT,
  partkey BIGINT NOT NULL,
  suppkey BIGINT NOT NULL,
  extendedprice DOUBLE NOT NULL,
  discount DOUBLE NOT NULL,
  returnflag CHAR(1) NOT NULL,
  linestatus CHAR(1) NOT NULL,
  shipdate DATE NOT NULL,
  shipmode VARCHAR(25) NOT NULL,
  commitdate DATE NOT NULL,
  receiptdate DATE NOT NULL
);

CREATE TABLE orders (
  orderkey BIGINT PRIMARY KEY,
  custkey BIGINT NOT NULL,
  orderstatus VARCHAR(1) NOT NULL,
  totalprice DOUBLE NOT NULL,
  orderdate DATE NOT NULL
);

CREATE TABLE partsupp (
  partkey INTEGER NOT NULL PRIMARY KEY,
  suppkey INTEGER NOT NULL,
  availqty INTEGER NOT NULL,
  supplycost DECIMAL(15,2) NOT NULL
);

Exact match rewrite

Ketika struktur kueri identik dengan definisi materialized view, mesin langsung menulis ulang kueri tersebut.

Query

SELECT
  l.returnflag,
  l.linestatus,
  SUM(l.extendedprice * (1 - l.discount)),
  COUNT(*) AS count_order
FROM lineitem AS l
GROUP BY l.returnflag, l.linestatus;

Materialized view

CREATE MATERIALIZED VIEW mv0
REFRESH NEXT now() + interval 1 day
ENABLE QUERY REWRITE
AS
SELECT
  l.returnflag,
  l.linestatus,
  SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price,
  COUNT(*) AS count_order
FROM lineitem AS l
GROUP BY l.returnflag, l.linestatus;

Rewritten query

SELECT returnflag, linestatus, sum_disc_price, count_order
FROM mv0;

Advanced query rewrite

FILTER

Ketika predikat kueri lebih sempit daripada predikat materialized view, mesin menambahkan klausa WHERE ke pemindaian materialized view untuk menerapkan filter yang hilang. Jika suatu ekspresi dalam kueri tidak ada dalam materialized view, mesin juga berusaha menghitung ekspresi tersebut dari view tersebut.

Query

SELECT
  l.shipmode,
  l.extendedprice * (1 - l.discount) AS disc_price
FROM orders AS o, lineitem AS l
WHERE o.orderkey = l.orderkey
  AND l.shipmode IN ('REG AIR', 'TRUCK')
  AND l.commitdate < l.receiptdate
  AND l.shipdate < l.commitdate;

Materialized view

CREATE MATERIALIZED VIEW mv1
REFRESH NEXT now() + interval 1 day
ENABLE QUERY REWRITE
AS
SELECT
  l.shipmode,
  l.extendedprice,
  l.discount
FROM orders AS o, lineitem AS l
WHERE o.orderkey = l.orderkey
  AND l.commitdate < l.receiptdate
  AND l.shipdate < l.commitdate;

Rewritten query

SELECT
  shipmode,
  extendedprice * (1 - discount) AS disc_price,
  discount
FROM mv1
WHERE shipmode IN ('REG AIR', 'TRUCK');

JOIN

Ketika kueri dan materialized view memiliki hubungan join yang berbeda, mesin menurunkan join yang diperlukan dari materialized view. Misalnya, materialized view dengan outer join dapat memenuhi kueri yang membutuhkan inner join dengan memfilter baris null.

Jenis join yang didukung: inner join, outer join, left join, dan right join.

Query

SELECT
  p.type,
  p.partkey,
  ps.suppkey
FROM part AS p, partsupp AS ps
WHERE p.partkey = ps.partkey
  AND p.type NOT LIKE 'MEDIUM POLISHED%';

Materialized view

CREATE MATERIALIZED VIEW mv2
REFRESH NEXT now() + INTERVAL 1 day
ENABLE QUERY REWRITE
AS
SELECT
  p.type,
  p.partkey,
  ps.suppkey
FROM partsupp AS ps
INNER JOIN part AS p ON p.partkey = ps.partkey
WHERE p.type NOT LIKE 'MEDIUM POLISHED%';

Rewritten query

SELECT type, partkey, suppkey
FROM mv2;

AGGREGATION

Ketika kueri atau materialized view menggunakan klausa GROUP BY atau fungsi agregat yang berbeda, mesin membangun fungsi agregat yang sama dari materialized view menggunakan aturan AGGREGATION.

Query

SELECT
  l.returnflag,
  l.linestatus,
  SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price
FROM lineitem AS l
GROUP BY l.returnflag, l.linestatus;

Materialized view

CREATE MATERIALIZED VIEW mv3
REFRESH NEXT now() + INTERVAL 1 day
ENABLE QUERY REWRITE
AS
SELECT
  l.returnflag,
  l.linestatus,
  SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price,
  COUNT(*) AS count_order
FROM lineitem AS l
GROUP BY l.returnflag, l.linestatus;

Rewritten query

SELECT returnflag, linestatus, sum_disc_price, count_order
FROM mv3;

AGGREGATION ROLLUP

Ketika kueri melakukan pengelompokan berdasarkan subset bidang GROUP BY materialized view, mesin melakukan roll-up terhadap agregat yang telah diproses sebelumnya.

Query

SELECT
  l.returnflag,
  SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price,
  COUNT(*) AS count_order
FROM lineitem AS l
WHERE l.returnflag = 'R'
GROUP BY l.returnflag;

Materialized view

CREATE MATERIALIZED VIEW mv4
REFRESH NEXT now() + INTERVAL 1 day
ENABLE QUERY REWRITE
AS
SELECT
  l.returnflag,
  l.linestatus,
  SUM(l.extendedprice * (1 - l.discount)) AS sum_disc_price,
  COUNT(*) AS count_order
FROM lineitem AS l
GROUP BY l.returnflag, l.linestatus;

Rewritten query

SELECT
  returnflag,
  linestatus,
  sum_disc_price,
  count_order
FROM mv4
WHERE returnflag = 'R'
GROUP BY returnflag;

SUBQUERIES

Ketika kueri menggunakan subkueri sebagai pengganti tabel dasar, mesin memeriksa apakah materialized view mencakup seluruh tabel dan mendorong filter subkueri ke dalam pemindaian yang ditulis ulang.

Query

SELECT
  p.type,
  p.partkey,
  ps.suppkey
FROM part AS p,
  (SELECT * FROM partsupp WHERE suppkey > 10) ps
WHERE p.partkey = ps.partkey;

Materialized view

CREATE MATERIALIZED VIEW mv5
REFRESH NEXT now() + INTERVAL 1 day
ENABLE QUERY REWRITE
AS
SELECT
  p.type,
  p.partkey,
  ps.suppkey
FROM part AS p, partsupp AS ps
WHERE p.partkey = ps.partkey;

Rewritten query

SELECT type, partkey, suppkey
FROM mv5
WHERE suppkey > 10;

QUERY PARTIAL

Ketika kueri mereferensikan tabel yang tidak dicakup oleh materialized view, mesin melakukan join antara materialized view dengan tabel yang hilang tersebut.

Query

SELECT
  p.type,
  p.partkey,
  ps.suppkey
FROM part AS p, partsupp AS ps
WHERE p.partkey = ps.partkey
  AND p.type NOT LIKE 'MEDIUM POLISHED%';

Materialized view

CREATE MATERIALIZED VIEW mv6
REFRESH NEXT now() + INTERVAL 1 day
ENABLE QUERY REWRITE
AS
SELECT
  p.type,
  p.partkey
FROM part AS p
WHERE p.type NOT LIKE 'MEDIUM POLISHED%';

Rewritten query

SELECT
  mv6.type,
  mv6.partkey,
  ps.suppkey
FROM mv6, partsupp AS ps
WHERE mv6.partkey = ps.partkey;

UNION

Ketika materialized view hanya mencakup sebagian rentang tanggal atau nilai kueri, mesin mengambil bagian yang tercakup dari materialized view dan mengambil baris sisanya langsung dari tabel dasar, lalu menggabungkan hasilnya dengan UNION ALL.

Query

SELECT
  l.linestatus,
  COUNT(*) AS count_order
FROM lineitem AS l
WHERE l.shipdate >= DATE '1998-01-01'
GROUP BY l.linestatus;

Materialized view (hanya mencakup shipdate >= 2000-01-01)

CREATE MATERIALIZED VIEW mv7
REFRESH NEXT now() + interval 1 day
ENABLE QUERY REWRITE
AS
SELECT
  l.linestatus,
  COUNT(*) AS count_order
FROM lineitem AS l
WHERE l.shipdate >= DATE '2000-01-01'
GROUP BY l.linestatus;

Rewritten query

SELECT linestatus, count_order
FROM (
    SELECT linestatus, count_order
    FROM mv7
  UNION ALL
    SELECT
      l.linestatus,
      COUNT(*) AS count_order
    FROM lineitem AS l
    WHERE l.shipdate >= DATE '1998-01-01' AND l.shipdate < DATE '1998-01-01'
    GROUP BY l.linestatus
)
GROUP BY linestatus;

Batasan

Exact match rewrite

Metode exact match rewrite tidak diaktifkan jika materialized view berisi:

  • Fungsi nondeterministik: NOW, CURRENT_TIMESTAMP, RANDOM

  • Fungsi yang ditentukan pengguna (UDFs)

Advanced query rewrite

Metode advanced query rewrite tidak diaktifkan jika materialized view berisi salah satu dari hal berikut:

  • Klausa ORDER BY, LIMIT, atau OFFSET

  • Klausa UNION atau UNION ALL

  • GROUPING SETS, CUBE, atau ROLLUP dalam klausa GROUP BY

  • Fungsi window

  • FULL OUTER JOIN

  • Tabel sistem

  • Subkueri berkorelasi

  • Fungsi nondeterministik: NOW, CURRENT_TIMESTAMP, RANDOM

  • UDFs

  • Klausa HAVING

  • SELF JOIN

Jenis pernyataan tempat query rewrite tidak pernah diaktifkan

Query rewrite tidak berlaku untuk kueri yang tertanam dalam jenis pernyataan berikut, terlepas dari definisi materialized view:

  • CREATE TABLE AS SELECT

  • INSERT INTO SELECT

  • INSERT OVERWRITE SELECT

  • REPLACE INTO SELECT

  • DELETE atau UPDATE

Kueri satu tabel tanpa filter atau agregat

Query rewrite tidak diaktifkan untuk kueri satu tabel yang tidak memiliki kondisi filter dan tidak memiliki fungsi agregat.

Pemecahan masalah

Query rewrite tidak diaktifkan setelah saya membuat materialized view.

Mulailah dari penyebab paling umum:

  1. Query rewrite tidak diaktifkan pada materialized view. Jalankan ALTER MATERIALIZED VIEW <mv_name> ENABLE QUERY REWRITE; dan coba lagi.

  2. Materialized view mencapai batasan. Tinjau bagian Limitations dan periksa apakah definisi materialized view Anda mencakup klausa atau fungsi yang tidak didukung.

  3. Izin SELECT pada materialized view tidak tersedia. Berikan izin yang diperlukan kepada akun yang menjalankan kueri:

    GRANT SELECT ON <database>.<mv_name> TO '<account>';

    Untuk detail selengkapnya, lihat bagian Required permissions dalam topik Query data from a materialized view.

Langkah berikutnya