All Products
Search
Document Center

MaxCompute:Penulisan ulang kueri tampilan yang di-materialisasi

Last Updated:Jan 01, 2026

MaxCompute mendukung penulisan ulang pernyataan SQL asli yang berisi kondisi filter atau jenis operator tertentu agar menggunakan tampilan yang di-materialisasi. Topik ini menjelaskan langkah-langkah penulisan ulang kueri SQL.

Lingkup

  • Agar suatu kueri dapat ditulis ulang, tampilan yang di-materialisasi harus mencakup semua data yang dibutuhkan oleh kueri tersebut, termasuk kolom output, kolom dalam kondisi filter, fungsi agregat, serta kondisi JOIN. Jika tampilan yang di-materialisasi tidak memiliki kolom yang diperlukan atau menggunakan fungsi agregat yang tidak didukung, kueri tersebut tidak dapat ditulis ulang.

  • Untuk mengaktifkan penulisan ulang kueri, tambahkan konfigurasi berikut sebelum pernyataan kueri Anda:

    SET odps.sql.materialized.view.enable.auto.rewriting=true;

    Jika tampilan yang di-materialisasi tidak valid, penulisan ulang kueri tidak didukung, dan kueri akan dijalankan terhadap tabel sumber tanpa percepatan.

  • Penulisan ulang lintas proyek

    Secara default, sebuah Proyek MaxCompute hanya dapat menggunakan tampilan yang di-materialisasi miliknya sendiri untuk penulisan ulang kueri. Untuk menggunakan tampilan yang di-materialisasi dari proyek lain, tambahkan konfigurasi berikut sebelum pernyataan kueri Anda guna menentukan daftar Proyek MaxCompute lainnya:

    SET odps.sql.materialized.view.source.project.white.list = <project_name1>,<project_name2>,<project_name3>;
  • Untuk menulis ulang kueri pada tampilan yang di-materialisasi yang mengandung kata kunci LEFT/RIGHT JOIN atau UNION ALL, tambahkan konfigurasi berikut sebelum pernyataan kueri Anda:

    SET odps.sql.materialized.view.enable.substitute.rewriting=true;

Tabel perbandingan jenis operator

Tabel berikut membandingkan jenis operator yang didukung MaxCompute untuk penulisan ulang kueri tampilan yang di-materialisasi dengan Produk lainnya.

Jenis Operator

Klasifikasi

MaxCompute

BigQuery

Amazon RedShift

Hive

FILTER

Pencocokan ekspresi lengkap

Dukungan

Dukungan

Dukungan

Dukungan

Pencocokan ekspresi parsial

Dukungan

Didukung

Didukung

Dukungan

AGGREGATE

AGGREGATE Tunggal

Dukungan

Dukungan

Didukung

Didukung

Beberapa AGGREGATE

Tidak didukung

Tidak didukung

Tidak didukung

Tidak didukung

JOIN

Jenis JOIN

INNER JOIN

Tidak didukung

INNER JOIN

INNER JOIN

JOIN Tunggal

Dukungan

Tidak didukung

Dukungan

Dukungan

Beberapa JOIN

Didukung

Tidak didukung

Dukungan

Dukungan

AGGREGATE+JOIN

-

Dukungan

Tidak didukung

Dukungan

Dukungan

Contoh

Contoh 1: Menulis ulang pernyataan kueri dengan kondisi filter

  1. Buat tampilan yang di-materialisasi.

    CREATE MATERIALIZED VIEW mv AS SELECT a,b,c FROM src WHERE a>5;
  2. Tabel berikut membandingkan pernyataan kueri asli dengan pernyataan yang telah ditulis ulang berdasarkan tampilan yang di-materialisasi yang dibuat.

    Pernyataan kueri asli

    Pernyataan kueri yang ditulis ulang

    SELECT a,b FROM src WHERE a>5;
    SELECT a,b FROM mv;
    SELECT a, b FROM src WHERE a=10;
    SELECT a,b FROM mv WHERE a=10;
    SELECT a, b FROM src WHERE a=10 AND b=3;
    SELECT a,b FROM mv WHERE a=10 AND b=3;
    SELECT a, b FROM src WHERE a>3;
    (SELECT a,b FROM src WHERE a>3 AND a<=5) UNION (SELECT a,b FROM mv);
    SELECT a, b FROM src WHERE a=10 AND d=4;

    Penulisan ulang gagal karena kolom d tidak ada dalam tampilan yang di-materialisasi.

    SELECT d, e FROM src WHERE a=10;

    Penulisan ulang gagal karena kolom d dan e tidak ada dalam tampilan yang di-materialisasi.

    SELECT a, b FROM src WHERE a=1;

    Penulisan ulang gagal karena tampilan yang di-materialisasi tidak berisi data dengan a=1.

Contoh 2: Menulis ulang pernyataan kueri dengan fungsi agregat

Jika pernyataan SQL tampilan yang di-materialisasi dan pernyataan kueri memiliki kunci agregasi yang sama, semua fungsi agregat dapat ditulis ulang. Jika kunci agregasinya berbeda, hanya SUM, MIN, dan MAX yang didukung.

  1. Buat tampilan yang di-materialisasi.

    CREATE MATERIALIZED VIEW mv AS 
    SELECT a, b, sum(c) AS sum, count(d) AS cnt FROM src GROUP BY a, b;
  2. Tabel berikut membandingkan pernyataan kueri asli dengan pernyataan yang telah ditulis ulang berdasarkan tampilan yang di-materialisasi yang dibuat.

    Pernyataan kueri asli

    Pernyataan kueri yang ditulis ulang

    SELECT a, sum(c) FROM src GROUP BY a;
    SELECT a, sum(sum) FROM mv GROUP BY a;
    SELECT a, count(d) FROM src GROUP BY a, b;
    SELECT a, cnt FROM mv;
    SELECT a, count(b) FROM 
    (SELECT a, b FROM src GROUP BY a, b) GROUP BY a;
    SELECT a,count(b) FROM mv GROUP BY a;
    SELECT a,count(b) FROM mv GROUP BY a;

    Penulisan ulang gagal karena tampilan telah mengagregasi kolom a dan b, sehingga tidak dapat mengagregasi b lagi.

    SELECT a, count(c) FROM src GROUP BY a;

    Penulisan ulang gagal karena re-agregasi tidak didukung untuk fungsi COUNT.

Jika fungsi agregat mengandung DISTINCT, penulisan ulang kueri hanya dimungkinkan jika pernyataan tampilan yang di-materialisasi dan pernyataan kueri memiliki kunci agregasi yang sama.

  1. Buat tampilan yang di-materialisasi.

    CREATE MATERIALIZED VIEW mv AS 
    SELECT a, b, sum(DISTINCT c) AS sum, count(DISTINCT d) AS cnt FROM src GROUP BY a, b;
  2. Tabel berikut membandingkan pernyataan kueri asli dengan pernyataan yang telah ditulis ulang berdasarkan tampilan yang di-materialisasi yang dibuat.

    Pernyataan kueri asli

    Pernyataan kueri yang ditulis ulang

    SELECT a, count(DISTINCT d) FROM src GROUP BY a, b;
    SELECT a, cnt FROM mv;
    SELECT a, count(c) FROM src GROUP BY a, b;

    Penulisan ulang gagal karena re-agregasi tidak didukung untuk fungsi COUNT.

    SELECT a, count(DISTINCT c) FROM src GROUP BY a;

    Penulisan ulang gagal karena kolom a memerlukan agregasi tambahan.

Contoh 3: Menulis ulang pernyataan kueri dengan klausa JOIN

Menulis ulang input JOIN

  1. Buat tampilan yang di-materialisasi.

    CREATE MATERIALIZED VIEW mv1 AS SELECT a, b FROM j1 WHERE b > 10;
    CREATE MATERIALIZED VIEW mv2 AS SELECT a, b FROM j2 WHERE b > 10;
  2. Tabel berikut membandingkan pernyataan kueri asli dengan pernyataan yang telah ditulis ulang berdasarkan tampilan yang di-materialisasi yang dibuat.

    Pernyataan kueri asli

    Pernyataan kueri yang ditulis ulang

    SELECT j1.a,j1.b,j2.a FROM (SELECT a,b FROM j1 WHERE b > 10) j1 JOIN j2 ON j1.a=j2.a;
    SELECT mv1.a, mv1.b, j2.a FROM mv1 JOIN j2 ON mv1.a=j2.a;
    SELECT j1.a,j1.b,j2.a FROM 
    (SELECT a,b FROM j1 WHERE b > 10) j1 
    JOIN (SELECT a,b FROM j2 WHERE b > 10) j2 ON j1.a=j2.a;
    SELECT mv1.a,mv1.b,mv2.a FROM mv1 JOIN mv2 ON mv1.a=mv2.a;

JOIN dengan kondisi filter

  1. Buat tampilan yang di-materialisasi.

    -- Buat tampilan yang di-materialisasi non-partisi.
    CREATE MATERIALIZED VIEW mv1 AS SELECT j1.a, j1.b FROM j1 JOIN j2 ON j1.a=j2.a;
    CREATE MATERIALIZED VIEW mv2 AS SELECT j1.a, j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 10;
    -- Buat tampilan yang di-materialisasi partisi.
    CREATE MATERIALIZED VIEW mv LIFECYCLE 7 PARTITIONED BY (ds) AS SELECT t1.id, t1.ds AS ds FROM t1 JOIN t2 ON t1.id = t2.id;
  2. Tabel berikut membandingkan pernyataan kueri asli dengan pernyataan yang telah ditulis ulang berdasarkan tampilan yang di-materialisasi yang dibuat.

    Pernyataan kueri asli

    Pernyataan kueri yang ditulis ulang

    SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a=4;
    SELECT a, b FROM mv1 WHERE a=4;
    SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 20;
    SELECT a,b FROM mv2 WHERE a>20;
    SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 5;
    (SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j1.a > 5 AND j1.a <= 10) 
    UNION SELECT * FROM mv2;
    SELECT key FROM t1 JOIN t2 ON t1.id= t2.id WHERE t1.ds='20210306';
    SELECT key FROM mv WHERE ds='20210306';
    SELECT key FROM t1 JOIN t2 ON t1.id= t2.id WHERE t1.ds>='20210306';
    SELECT key FROM mv WHERE ds>='20210306';
    SELECT j1.a,j1.b FROM j1 JOIN j2 ON j1.a=j2.a WHERE j2.a=4;

    Penulisan ulang gagal karena tampilan yang di-materialisasi tidak memiliki kolom j2.a.

JOIN dengan tabel tambahan

  1. Buat tampilan yang di-materialisasi.

    CREATE MATERIALIZED VIEW mv AS SELECT j1.a, j1.b FROM j1 JOIN j2 ON j1.a=j2.a;
  2. Tabel berikut membandingkan pernyataan kueri asli dengan pernyataan yang telah ditulis ulang berdasarkan tampilan yang di-materialisasi yang dibuat.

    Pernyataan kueri asli

    Pernyataan kueri yang ditulis ulang

    SELECT j1.a, j1.b FROM j1 JOIN j2 JOIN j3 ON j1.a=j2.a AND j1.a=j3.a;
    SELECT mv.a, mv.b FROM mv JOIN j3 ON mv.a=j3.a;
    SELECT j1.a, j1.b FROM j1 JOIN j2 JOIN j3 ON j1.a=j2.a AND j2.a=j3.a;
    SELECT mv.a,mv.b FROM mv JOIN j3 ON mv.a=j3.a;

Ketiga jenis pernyataan di atas dapat dikombinasikan. Jika suatu pernyataan kueri memenuhi kondisi penulisan ulang, maka kueri tersebut dapat ditulis ulang.

Tujuan penulisan ulang kueri adalah untuk mempercepat eksekusi. MaxCompute memprioritaskan aturan penulisan ulang yang paling efektif. Jika penulisan ulang menambahkan operasi tanpa meningkatkan performa, MaxCompute tidak akan menggunakannya.

Contoh 4: Menulis ulang pernyataan kueri dengan klausa LEFT JOIN

  1. Buat tampilan yang di-materialisasi.

    CREATE MATERIALIZED VIEW mv LIFECYCLE 7(
            user_id,
            job,
            total_amount
    ) AS SELECT t1.user_id, t1.job, sum(t2.order_amount) AS total_amount 
          FROM user_info AS t1 LEFT JOIN sale_order AS t2 ON t1.user_id=t2.user_id GROUP BY t1.user_id;
  2. Tabel berikut membandingkan pernyataan kueri asli dengan pernyataan yang telah ditulis ulang berdasarkan tampilan yang di-materialisasi yang dibuat.

    Pernyataan kueri asli

    Pernyataan kueri yang ditulis ulang

    SELECT t1.user_id, sum(t2.order_amout) AS total_amount 
    FROM user_info AS t1 
    LEFT JOIN sale_order AS t2 ON t1.user_id=t2.user_id 
    GROUP BY t1.user_id;
    SELECT user_id, total_amount FROM mv;

Contoh 5: Menulis ulang pernyataan kueri dengan klausa UNION ALL

  1. Buat tampilan yang di-materialisasi.

    CREATE MATERIALIZED VIEW mv LIFECYCLE 7( 
            user_id, 
            tran_amount, 
            tran_date 
    ) AS SELECT user_id, tran_amount, tran_date FROM alipay_tran UNION ALL 
    SELECT user_id, tran_amount, tran_date FROM unionpay_tran;
  2. Tabel berikut membandingkan pernyataan kueri asli dengan pernyataan yang telah ditulis ulang berdasarkan tampilan yang di-materialisasi yang dibuat.

    Pernyataan kueri asli

    Pernyataan kueri yang ditulis ulang

    SELECT user_id, tran_amount FROM alipay_tran 
    UNION ALL SELECT user_id, tran_amount FROM unionpay_tran;
    SELECT user_id, total_amount FROM mv;

Contoh 6: Skenario

  1. Skenario Contoh

    Asumsikan Anda memiliki tabel akses halaman bernama visit_records. Tabel ini mencatat ID halaman, ID pengguna, dan waktu akses untuk setiap kunjungan. Anda sering perlu melakukan kueri dan menganalisis jumlah kunjungan ke berbagai halaman.

    Dalam kasus ini, Anda dapat membuat tampilan yang di-materialisasi untuk tabel visit_records yang mengelompokkan data berdasarkan ID halaman dan menghitung jumlah kunjungan untuk setiap halaman. Kemudian, Anda dapat menjalankan kueri berdasarkan tampilan yang di-materialisasi ini.

    Struktur tabel visit_records adalah sebagai berikut:

    +------------------------------------------------------------------------------------+
    | Field           | Type       | Label | Comment                                     |
    +------------------------------------------------------------------------------------+
    | page_id         | string     |       |                                             |
    | user_id         | string     |       |                                             |
    | visit_time      | string     |       |                                             |
    +------------------------------------------------------------------------------------+
  2. Buat tampilan yang di-materialisasi.

    -- Buat tampilan yang di-materialisasi untuk tabel visit_records. Tampilan ini mengelompokkan data berdasarkan ID halaman dan menghitung jumlah kunjungan untuk setiap halaman.
    
    CREATE MATERIALIZED VIEW count_mv AS SELECT page_id, count(*) FROM visit_records GROUP BY page_id;
  3. Jalankan pernyataan kueri berikut.

    SET odps.sql.materialized.view.enable.auto.rewriting=true; 
    SELECT page_id, count(*) FROM visit_records GROUP BY page_id;

    Saat Anda menjalankan kueri ini, MaxCompute secara otomatis menulis ulang kueri tersebut untuk menggunakan tampilan yang di-materialisasi count_mv dan membaca data agregat dari count_mv.

  4. Jalankan perintah berikut untuk memeriksa apakah kueri telah ditulis ulang untuk menggunakan tampilan yang di-materialisasi.

    EXPLAIN SELECT page_id, count(*) FROM visit_records GROUP BY page_id;

    Hasil berikut dikembalikan:

    job0 is root job
    
    In Job job0:
    root Tasks: M1
    
    In Task M1:
        Data source: doc_test_dev.count_mv
        TS: doc_test_dev.count_mv
            FS: output: Screen
                schema:
                  page_id (string)
                  _c1 (bigint)
    
    
    OK

    Field Data source dalam hasil yang dikembalikan menunjukkan bahwa kueri membaca data dari tabel count_mv dalam proyek doc_test_dev. Hal ini menunjukkan bahwa tampilan yang di-materialisasi berfungsi dan penulisan ulang kueri berhasil.

Topik terkait