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.
CatatanUntuk 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:
Pada saat pembuatan, sertakan klausa
ENABLE QUERY REWRITEdalam pernyataanCREATE MATERIALIZED VIEWAnda. Lihat Create a materialized view — Parameters.Setelah pembuatan, jalankan:
ALTER MATERIALIZED VIEW <mv_name> ENABLE QUERY REWRITE;
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
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;Setelah mengaktifkan query rewrite, jalankan
EXPLAINpada kueri tersebut.EXPLAIN SELECT course_id, course_name, max(course_grade) AS max_grade FROM tb_courses;Periksa rencana eksekusi. Saat query rewrite aktif, baris
TableScanmenampilkan 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,RANDOMFungsi 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, atauOFFSETKlausa
UNIONatauUNION ALLGROUPING SETS,CUBE, atauROLLUPdalam klausaGROUP BYFungsi window
FULL OUTER JOINTabel sistem
Subkueri berkorelasi
Fungsi nondeterministik:
NOW,CURRENT_TIMESTAMP,RANDOMUDFs
Klausa
HAVINGSELF 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 SELECTINSERT INTO SELECTINSERT OVERWRITE SELECTREPLACE INTO SELECTDELETEatauUPDATE
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:
Query rewrite tidak diaktifkan pada materialized view. Jalankan
ALTER MATERIALIZED VIEW <mv_name> ENABLE QUERY REWRITE;dan coba lagi.Materialized view mencapai batasan. Tinjau bagian Limitations dan periksa apakah definisi materialized view Anda mencakup klausa atau fungsi yang tidak didukung.
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.