All Products
Search
Document Center

Hologres:Panduan lengkap mengenai materialized view

Last Updated:Mar 12, 2026

Materialized view real-time melakukan pra-agregasi dan menyimpan data dari tabel dasar. Mengkueri materialized view mengurangi beban komputasi serta secara signifikan meningkatkan performa kueri. Topik ini menjelaskan cara menggunakan materialized view di Hologres.

Informasi latar belakang

Data dalam materialized view real-time di Hologres tidak perlu direfresh secara manual. Ketika data ditulis ke tabel dasar, perubahan tersebut langsung tercermin dalam kueri terhadap materialized view. Data menjadi terlihat dan teragregasi segera setelah ditulis.

结构图Dalam materialized view real-time, tabel yang menerima penulisan real-time disebut tabel dasar. Semua operasi INSERT, UPDATE, dan DELETE dilakukan pada tabel dasar. Materialized view didefinisikan berdasarkan aturan agregasi pada tabel dasar. Ketika tabel dasar berubah, perubahan tersebut disinkronkan ke materialized view secara real-time. Saat ini, hanya perubahan dari operasi INSERT yang didukung. Dukungan untuk jenis perubahan lainnya akan ditambahkan di masa mendatang.

Batasan

  • Materialized view real-time tidak mendukung operasi DELETE atau UPDATE pada tabel dasar. Anda harus mengatur properti appendonly untuk tabel dasar. Jika Anda mencoba melakukan operasi DELETE atau UPDATE pada tabel dasar, kesalahan Table XXX is append-only akan dikembalikan. Saat menulis data secara real-time menggunakan Flink, properti mutateType harus diatur ke InsertOrIgnore.

  • Pembuatan materialized view secara asinkron tidak didukung. Anda harus membuat materialized view bersamaan dengan pembuatan tabel dasar.

  • Materialized view hanya dapat dibuat untuk satu tabel tunggal. Materialized view tidak mendukung common table expressions (CTE), JOIN antar beberapa tabel, subkueri, atau klausa WHERE, ORDER BY, LIMIT, dan HAVING.

  • Kunci GROUP BY dan nilai dalam materialized view real-time tidak mendukung ekspresi. Misalnya, SUM(CASE WHEN COND THEN A ELSE B END), SUM(col1 + col2), dan GROUP BY date_trunc('hour', ts) tidak didukung.

  • Maksimal 10 materialized view dapat dibuat untuk setiap tabel dasar. Konsumsi sumber daya meningkat sebanding dengan jumlah materialized view.

  • Jika materialized view dibuat untuk tabel partisi, kunci GROUP BY materialized view harus mencakup kolom kunci partisi. Materialized view hanya dapat dibuat untuk tabel induk, bukan untuk tabel anaknya.

  • Jika materialized view dibuat untuk tabel partisi, sintaksis ATTACH PARTITION tidak didukung untuk menyambungkan partisi ke tabel induk. Namun, sintaksis CREATE TABLE PARTITION OF didukung.

  • Operasi DROP COLUMN tidak didukung pada tabel dasar yang memiliki materialized view.

  • Data dasar materialized view memiliki masa hidup data (TTL) yang sama dengan tabel dasarnya. Jangan mengatur TTL secara manual untuk materialized view. Jika tidak, ketidakkonsistenan data dapat terjadi antara materialized view dan tabel dasar.

Fungsi agregat yang didukung

Saat ini, materialized view mendukung fungsi agregat berikut.

  • SUM

  • COUNT

  • AVG

  • MIN

  • MAX

  • RB_BUILD_CARDINALITY_AGG (Hanya mendukung tipe data BIGINT. Ekstensi roaringbitmap harus dibuat terlebih dahulu.)

Contoh SQL

  • Buat materialized view real-time

    BEGIN;
    CREATE TABLE base_sales(
      day text not null,
      hour int ,
      ts timestamptz,
      amount float,
      pk text not null primary key
    );
    CALL SET_TABLE_PROPERTY('base_sales', 'mutate_type', 'appendonly');
    
    -- Setelah materialized view real-time dihapus, Anda dapat menghapus properti appendonly dari tabel dasar dengan menjalankan perintah berikut:
    --CALL SET_TABLE_PROPERTY('base_sales', 'mutate_type', 'none');
    
    CREATE MATERIALIZED VIEW mv_sales AS
      SELECT
        day,
        hour,
        avg(amount) AS amount_avg
      FROM base_sales
      GROUP BY day, hour;
    
    COMMIT;
    
    insert into base_sales values(to_char(now(),'YYYYMMDD'),'12',now(),100,'pk1');
    insert into base_sales values(to_char(now(),'YYYYMMDD'),'12',now(),200,'pk2');
    insert into base_sales values(to_char(now(),'YYYYMMDD'),'12',now(),300,'pk3');
  • Buat materialized view untuk tabel partisi

    BEGIN;
    CREATE TABLE base_sales_p(
      day text not null,
      hour int,
      ts timestamptz,
      amount float,
      pk text not null,
      primary key (day, pk)
    ) partition by list(day);
    CALL SET_TABLE_PROPERTY('base_sales_p', 'mutate_type', 'appendonly');
    
    -- day adalah kolom kunci partisi dan harus dimasukkan dalam klausa GROUP BY view.
    CREATE MATERIALIZED VIEW mv_sales_p AS
      SELECT
        day,
        hour,
        avg(amount) AS amount_avg
      FROM base_sales_p
      GROUP BY day, hour;
    COMMIT;
    
    create table base_sales_20220101 partition of base_sales_p for values in('20220101');
  • Kueri materialized view

    SELECT * FROM mv_sales WHERE day = to_char(now(),'YYYYMMDD') AND hour = 12;
  • Hapus materialized view

    DROP MATERIALIZED VIEW mv_sales;
  • Menanyakan ruang penyimpanan Tampilan yang di-materialisasi

    select pg_relation_size('mv_sales');
  • Kueri total storage space dasar semua materialized view

    SELECT schemaname || '.' || matviewname AS mv_full_name,
    pg_size_pretty(pg_relation_size('"' || schemaname || '"."' || matviewname || '"')) AS mv_size,
    pg_relation_size('"' || schemaname || '"."' || matviewname || '"') AS  order_size
    FROM pg_matviews
    ORDER BY order_size DESC;

Gunakan materialized view untuk meningkatkan performa perhitungan UV presisi

Perhitungan unique visitor (UV) presisi merupakan operator dengan kompleksitas komputasi tinggi dan sering menjadi bottleneck performa sistem. Hologres mendukung fungsi agregat RB_BUILD_CARDINALITY_AGG. Dengan menggunakan struktur data RoaringBitmap, Anda dapat melakukan pra-agregasi data BIGINT—yang biasanya merepresentasikan bidang ID bisnis—ke dalam materialized view. Proses ini mencapai deduplikasi real-time untuk statistik UV. Anda dapat membuat materialized view sebagai berikut. Saat ini, hanya agregasi dan deduplikasi untuk bidang BIGINT yang didukung.

-- Perhitungan UV bergantung pada tipe data RoaringBitmap. Ekstensi RoaringBitmap harus dibuat terlebih dahulu.
CREATE EXTENSION if not exists roaringbitmap;

BEGIN;
CREATE TABLE base_sales_r(
  day text not null,
  hour int ,
  ts timestamptz,
  amount float,
  userid bigint,
  pk text not null primary key
);
CALL SET_TABLE_PROPERTY('base_sales_r', 'mutate_type', 'appendonly');

CREATE MATERIALIZED VIEW mv_sales_r AS
  SELECT
    day,
    hour,
    avg(amount) AS amount_avg,
    rb_build_cardinality_agg(userid) as user_count
  FROM base_sales_r
  GROUP BY day, hour;

COMMIT;

insert into base_sales_r values(to_char(now(),'YYYYMMDD'),'12',now(),100,1,'pk1');
insert into base_sales_r values(to_char(now(),'YYYYMMDD'),'12',now(),200,2,'pk2');
insert into base_sales_r values(to_char(now(),'YYYYMMDD'),'12',now(),300,3,'pk3');
select user_count as UV from mv_sales_r where day = to_char(now(),'YYYYMMDD') AND hour = 12;

Fungsi rb_build_cardinality_agg menghitung jumlah nilai unik. Dalam view mv_sales_r, user_count merepresentasikan jumlah nilai unik dari userid. Anda dapat mengkueri bidang user_count untuk memperoleh jumlah nilai unik tersebut.

Gunakan materialized view untuk mendukung kueri agregat multi-dimensi

Asumsikan Anda telah mendefinisikan materialized view mv_sales dan tabel dasar base_sales berisi data berikut.

Day

Hour

Amount

PK

20210101

12

2

pk1

20210101

12

4

pk2

20210101

13

6

pk3

Kueri langsung pada sales_mv menghasilkan hasil berikut.

postgres=> select * from mv_sales;
    day    |   hour  |   amount_avg
-----------+---------+--------------
  20210101 |    12   |     3
  20210101 |    13   |     6

Jika Anda kemudian mencoba mengubah dimensi agregasi materialized view, misalnya dengan melakukan agregasi avg berdasarkan dimensi day, Anda akan memperoleh hasil yang salah. Hal ini karena rata-rata dari rata-rata tidak sama dengan rata-rata keseluruhan.

postgres=> select day, avg(amount_avg) from mv_sales group by day;
    day    |   avg
-----------+--------
  20210101 |   4.5

Salah satu solusinya adalah membuat materialized view lain yang diagregasi berdasarkan day. Namun, hal ini meningkatkan jumlah materialized view. Hologres menyediakan metode berbasis status agregasi antara yang memungkinkan Anda menggunakan satu materialized view untuk melakukan kueri agregat lintas dimensi berbeda. Contoh berikut menggunakan fungsi AVG. Anda dapat memodifikasi definisi view sebagai berikut.

BEGIN;
CREATE TABLE base_sales(
  day text not null,
  hour int ,
  ts timestamptz,
  amount float,
  pk text not null primary key
);
CALL SET_TABLE_PROPERTY('base_sales', 'mutate_type', 'appendonly');

CREATE MATERIALIZED VIEW mv_sales_partial AS
  SELECT
    day,
    hour,
    avg(amount) as avg,
    avg_partial(amount) AS amt_avg_partial
  FROM base_sales
  GROUP BY day, hour;

COMMIT;

Fungsi agregat avg asli didefinisikan ulang sebagai fungsi agregat avg_partial. Kolom amount_avg_partial menyimpan status antara dari hasil agregasi. Saat menjalankan kueri, modifikasi kueri agar menggunakan fungsi avg_final. Hal ini menunjukkan bahwa kueri sedang melakukan agregasi akhir pada status antara tersebut.

postgres=> select day, avg(avg) as avg_avg, avg_final(amt_avg_partial) as real_avg from mv_sales_partial group by day;
    day    |   avg_avg |  real_avg
-----------+-----------+----------
  20210101 |    4.5    |     4

Fungsi agregat yang didukung beserta fungsi agregat parsialnya adalah sebagai berikut.

Fungsi agregat standar

Fungsi agregat parsial

Fungsi agregat akhir

AVG

AVG_PARTIAL

AVG_FINAL

RB_BUILD_CARDINALITY_AGG

RB_BUILD_AGG

RB_OR_CARDINALITY_AGG

Penjelasan TTL

Jika TTL diatur untuk tabel dasar yang memiliki materialized view, Hologres tidak dapat menjamin konsistensi data antara tabel dasar dan materialized view untuk data yang mendekati ambang batas kedaluwarsa TTL. Mengkueri data tersebut dari materialized view menghasilkan perilaku yang tidak terdefinisi. Contoh berikut menggunakan tabel dasar base_sales_table dan materialized view sales_mv.

TTL diatur untuk tabel base_sales_table. Jika data direklaim karena TTL-nya kedaluwarsa, kueri pada tabel dasar menghasilkan hasil berikut.

postgres=> SELECT
    day,
    hour,
    avg(amount) AS amount_avg
  FROM base_sales
  GROUP BY day, hour;

--Hasil kueri
    day    |   hour  |   amount_avg
-----------+---------+--------------
  20210101 |    12   |     4
  20210101 |    13   |     6

Namun, karena data yang direklaim telah dimaterialisasi dalam view, kueri pada materialized view mungkin menghasilkan hasil berikut.

postgres=> select * from mv_sales;
--Hasil kueri
    day    |   hour  |   amount_avg
-----------+---------+--------------
  20210101 |    12   |     3
  20210101 |    13   |     6

Hasil kueri tidak konsisten. Solusi berikut direkomendasikan:

  • Jangan mengatur TTL untuk tabel detail.

  • Atur TTL untuk tabel dasar, tetapi pastikan kunci GROUP BY materialized view mencakup bidang berbasis waktu. Saat mengkueri materialized view, hindari mengkueri data yang mendekati ambang batas kedaluwarsa TTL.

  • Buat tabel dasar sebagai tabel partisi dan jangan atur TTL. Reklaim data dengan menghapus partisi anak.

Praktik terbaik penggunaan materialized view real-time

  • Saat membuat tabel dasar dan materialized view-nya, atur kunci GROUP BY materialized view agar sama dengan kunci distribusi tabel dasar. Praktik ini dapat meningkatkan rasio kompresi data dan performa kueri.

  • Saat mendefinisikan materialized view, letakkan kolom yang sering digunakan dalam kondisi filter di awal kunci GROUP BY. Praktik ini mengikuti prinsip pencocokan paling kiri dari kunci pengelompokan.

Routing cerdas untuk materialized view

Anda tidak perlu secara eksplisit menentukan nama materialized view dalam kueri Anda. Sebaliknya, Anda dapat langsung mengkueri tabel dasar. Jika terdapat materialized view yang sesuai, pengoptimal secara cerdas mengarahkan kueri ke materialized view yang paling tepat untuk mempercepat kueri. Pengoptimal memilih materialized view berdasarkan kriteria berikut:

  • Materialized view berisi semua kolom yang dikueri atau kolom yang nilainya dapat dihitung secara tidak langsung dari kolom yang dikueri.

  • Kolom GROUP BY materialized view mencakup semua kolom dari klausa GROUP BY kueri asli.

  • Jika beberapa materialized view memenuhi kriteria di atas, pengoptimal memilih yang memiliki jumlah kolom paling sedikit dalam kunci GROUP BY-nya.

Fungsi agregat yang mendukung routing cerdas adalah SUM, COUNT, MIN, dan MAX.