All Products
Search
Document Center

Realtime Compute for Apache Flink:Optimalkan Flink SQL

Last Updated:Aug 21, 2026

Tingkatkan throughput dan kurangi latensi penerapan Flink SQL dengan menyesuaikan sumber daya, mengaktifkan optimasi agregasi, serta menulis ulang pola SQL.

Tetapkan parameter garis dasar untuk throughput

Tambahkan parameter berikut ke bidang Other Configuration di bagian Parameters pada tab Configuration. Parameter ini meningkatkan throughput dan mengurangi masalah hotspot. Konfigurasikan parameter penerapan kustom.

execution.checkpointing.interval: 180s
table.exec.state.ttl: 129600000
table.exec.mini-batch.enabled: true
table.exec.mini-batch.allow-latency: 5s
table.optimizer.distinct-agg.split.enabled: true
Parameter Deskripsi
execution.checkpointing.interval Interval checkpoint. Nilai 180s berarti 180 detik.
state.backend Jenis backend status.
table.exec.state.ttl Masa aktif (TTL) data status, dalam milidetik.
table.exec.mini-batch.enabled Mengaktifkan agregasi miniBatch.
table.exec.mini-batch.allow-latency Latensi maksimum sebelum mini-batch dipicu.
table.exec.mini-batch.size Jumlah catatan maksimum per mini-batch. VVR mengoptimalkannya secara otomatis — biarkan tidak dikonfigurasi dalam sebagian besar kasus.Parameter utama.
table.optimizer.distinct-agg.split.enabled Mengaktifkan optimasi PartialFinal untuk COUNT DISTINCT.

Skalakan sumber daya penerapan

Ververica Platform (VVP) membatasi CPU JobManager dan TaskManager sesuai nilai yang dikonfigurasi. Tingkatkan nilai tersebut saat penerapan mengalami kendala sumber daya.

Skalakan sumber daya JobManager

Untuk penerapan paralel, tingkatkan sumber daya JobManager di bagian Resources pada tab Configuration. Contohnya:

  • Job Manager CPU: 4

  • Job Manager Memory: 8 GiB

Skalakan sumber daya TaskManager

Untuk topologi kompleks, tingkatkan sumber daya TaskManager di bagian Resources pada tab Configuration. Contohnya:

  • Task Manager CPU: 2

  • Task Manager Memory: 4 GiB

Catatan

Pertahankan taskmanager.numberOfTaskSlots pada nilai default-nya yaitu 1.

Optimalkan agregasi kelompok

Secara default, operator agregasi kelompok memproses catatan satu per satu: membaca akumulator dari status, memperbaruinya, menulis kembali, lalu mengulang proses tersebut. Pola per-catatan ini meningkatkan beban backend status — terutama dengan RocksDB — dan semakin memburuk pada kondisi hotspot data.

Aktifkan miniBatch

MiniBatch menyimpan catatan masuk dalam buffer dan memprosesnya secara bersamaan, sehingga mengurangi akses status per batch. Hal ini meningkatkan throughput dengan sedikit peningkatan latensi. Fitur miniBatch memicu pemrosesan mikro-batch berdasarkan pesan event yang dimasukkan di sumber pada interval tertentu.

Kapan digunakan: Skenario agregasi data yang tidak memerlukan latensi ultra-rendah.

Cara mengaktifkan: Tambahkan konfigurasi berikut ke bidang Other Configuration di bagian Parameters pada tab Configuration. Konfigurasikan parameter penerapan kustom.

table.exec.mini-batch.enabled: true
table.exec.mini-batch.allow-latency: 5s
Parameter Deskripsi
table.exec.mini-batch.enabled Atur ke true untuk mengaktifkan miniBatch.
table.exec.mini-batch.allow-latency Latensi maksimum sebelum mini-batch dipicu.
table.exec.mini-batch.size Jumlah catatan maksimum per mini-batch. Biarkan tidak dikonfigurasi — VVR mengoptimalkannya secara otomatis. Parameter utama.

Aktifkan LocalGlobal

LocalGlobal membagi agregasi menjadi dua tahap — pra-agregasi lokal di setiap node hulu, lalu agregasi global — mirip dengan combine dan reduce pada MapReduce. Agregasi lokal melakukan pra-filter terhadap data hotspot, sehingga mengurangi volume data yang mencapai tahap global.

Kapan digunakan: Fungsi agregat umum seperti SUM, COUNT, MAX, MIN, dan AVG yang mengalami masalah hotspot data.

Prasyarat:

  • MiniBatch harus diaktifkan. LocalGlobal menggunakan interval mini-batch untuk menentukan jumlah catatan yang diakumulasi sebelum agregasi lokal.

  • Fungsi agregat harus mengimplementasikan metode merge (AggregateFunction).

Status: Diaktifkan secara default saat miniBatch aktif.

Verifikasi: Periksa topologi akhir untuk keberadaan node GlobalGroupAggregate atau LocalGroupAggregate.

Aktifkan PartialFinal untuk COUNT DISTINCT

LocalGlobal kurang efektif untuk COUNT DISTINCT karena agregasi lokal tidak dapat menghapus duplikat kunci distinct. PartialFinal mengatasi hal ini dengan membagi agregasi menjadi dua lapisan: lapisan pertama menyebarkan data berdasarkan hash kunci distinct, lapisan kedua melakukan agregasi akhir.

Kapan digunakan: Kueri COUNT DISTINCT dengan volume data besar di mana performa agregasi menjadi bottleneck.

Cara mengaktifkan: Tambahkan konfigurasi berikut ke bidang Other Configuration. Konfigurasikan parameter penerapan kustom.

table.optimizer.distinct-agg.split.enabled: true

Batasan:

  • PartialFinal tidak dapat digunakan dalam SQL yang mengandung fungsi agregat yang didefinisikan pengguna (UDAF).

  • Aktifkan hanya untuk volume data besar. PartialFinal memperkenalkan shuffle jaringan tambahan.

Verifikasi: Periksa apakah agregasi satu lapisan berubah menjadi agregasi dua lapisan dalam topologi akhir.

Gunakan AGG WITH FILTER alih-alih CASE WHEN

Saat menghitung COUNT DISTINCT pada bidang yang sama dengan kondisi berbeda, gunakan klausa FILTER alih-alih CASE WHEN. Pengoptimal mengenali argumen filter berbeda pada kunci distinct yang sama dan menggunakan satu instance status bersama, sehingga mengurangi akses dan ukuran status. Uji performa menunjukkan peningkatan 2x dibandingkan CASE WHEN.

Sebelum (kurang efisien):

COUNT(DISTINCT visitor_id) AS uv_total,
COUNT(DISTINCT CASE WHEN is_wireless = 'y' THEN visitor_id ELSE NULL END) AS uv_wireless

Setelah (performa 2x):

COUNT(DISTINCT visitor_id) AS uv_total,
COUNT(DISTINCT visitor_id) FILTER (WHERE is_wireless = 'y') AS uv_wireless

Gunakan Delta Aggregation (agregasi tanpa status)

Catatan

Delta Aggregation hanya didukung dalam penerapan Realtime Compute for Apache Flink yang menggunakan VVR 11.8 atau lebih baru.

Delta Aggregation menyediakan agregasi tanpa status untuk agregasi kelompok streaming non-windowed. Berbeda dengan agregasi kelompok reguler yang terus-menerus memelihara akumulator agregat untuk setiap kelompok dalam status Flink, Delta Aggregation merespons perubahan data dengan menggunakan kunci pengelompokan untuk melakukan lookup asinkron terhadap catatan detail terkini dari kelompok tersebut dan menghitung ulang hasil agregat dari catatan tersebut.

Akibatnya, jumlah status agregasi di sisi Flink tidak lagi bergantung pada jumlah historis kelompok. Penerapan tidak perlu terus memperluas status agregasinya seiring bertambahnya jumlah kelompok. Hal ini mengurangi jumlah data yang dipersist di checkpoint, memperpendek waktu pemulihan, dan menstabilkan penggunaan sumber daya untuk penerapan agregasi kelompok skala besar.

Kasus penggunaan

Delta Aggregation melakukan lookup asinkron terhadap catatan detail terkini dari suatu kelompok dan menghitung ulang hasil agregat sesuai permintaan. Gunakan fitur ini untuk penerapan yang memiliki satu atau beberapa persyaratan berikut:

  • Setelah perubahan logika penerapan, agregasi kelompok reguler mengharuskan Anda memulai penerapan streaming tanpa status dan membangun kembali statusnya. Dengan Delta Aggregation, Anda dapat menjalankan penerapan batch tanpa status terlebih dahulu untuk memperbarui tabel hasil, lalu memulai penerapan streaming dengan status. Pendekatan ini memanfaatkan throughput tinggi pemrosesan batch untuk mempercepat backfill hasil dan pemulihan penerapan.

  • Mengurangi latensi checkpoint dan tekanan balik pemrosesan status saat status kelompok berukuran besar.

  • Mengurangi secara signifikan status agregasi yang harus dipulihkan saat penerapan dimulai ulang, sehingga memperpendek waktu pemulihan.

  • Mengurangi sumber daya komputasi dan penyimpanan yang digunakan oleh status agregasi serta menurunkan biaya unit komputasi (CU).

  • Berbagi status detail terkini di tabel sumber saat beberapa penerapan melakukan agregasi terhadap data detail yang sama.

  • Langsung mengkueri catatan detail terkini dari tabel sumber untuk memvalidasi hasil agregat dan mendiagnosis masalah.

Batasan

Struktur kueri
  • Hanya agregasi kelompok non-windowed tingkat tunggal dalam penerapan streaming yang didukung. Agregasi window dan agregasi bertingkat tidak didukung.

  • GROUP BY harus berisi kumpulan kolom yang langsung memetakan ke bidang tabel sumber dan harus mencakup kunci primer lengkap dari tabel sumber atau indeks yang dapat dikueri.

  • Ekspresi nondeterministik seperti PROCTIME() dan RAND() tidak didukung.

Tabel hulu dan hilir
  • Konektor sumber harus mendukung pemindaian streaming dan lookup asinkron.

  • Tabel sumber tidak boleh mendefinisikan watermark.

  • Catatan perubahan yang dikirimkan Delta Aggregation ke hilir hanya berisi UPDATE_AFTER (+U) dan DELETE (-D). Catatan tersebut tidak berisi UPDATE_BEFORE (-U).

Fungsi agregat
  • Fungsi berikut didukung: SUM, COUNT, AVG, MIN, MAX, LISTAGG, FIRST_VALUE, dan LAST_VALUE.

  • Agregasi DISTINCT, agregasi dengan klausa FILTER, fungsi agregat yang didefinisikan pengguna (UDAF), fungsi agregat Python, serta fungsi agregat lain yang tidak disebutkan tidak didukung.

Contoh

Platform e-commerce perlu memelihara jumlah catatan dan jumlah terkini untuk sejumlah besar pesanan. Platform tersebut menulis hasilnya ke tabel ringkasan agar layanan kueri pesanan dapat langsung mengambilnya berdasarkan merchant dan pesanan. Contoh berikut menggunakan kunci primer lengkap dari tabel sumber sebagai kunci lookup.

  1. Langkah 1: Buat tabel sumber dan tabel hasil.

    Tabel sumber harus mendukung pemindaian streaming dan lookup asinkron.

    CREATE TABLE orders (
      merchant_id BIGINT,                    -- ID Merchant
      order_id BIGINT,                       -- ID Pesanan
      amount DECIMAL(18, 2),                 -- Jumlah pesanan saat ini
      PRIMARY KEY (merchant_id, order_id) NOT ENFORCED
    ) WITH (
      'connector' = '<source-connector>',
      '<source-option>' = '<source-option-value>'
    );
    

    Gunakan semua bidang pengelompokan sebagai kunci primer tabel hasil.

    CREATE TABLE order_current_summary (
      merchant_id BIGINT,                    -- ID Merchant
      order_id BIGINT,                       -- ID Pesanan
      current_record_count BIGINT,           -- Jumlah catatan valid saat ini
      total_amount DECIMAL(38, 2),           -- Total jumlah saat ini
      PRIMARY KEY (merchant_id, order_id) NOT ENFORCED
    ) WITH (
      'connector' = '<sink-connector>',
      '<sink-option>' = '<sink-option-value>'
    );
    
  2. Langkah 2: Jalankan penerapan agregasi.

    Aktifkan Delta Aggregation sebelum pernyataan INSERT INTO:

    SET 'table.optimizer.delta-agg.strategy' = 'EVENTUAL';
    

    Gunakan SQL agregasi kelompok standar. Tidak diperlukan sintaks khusus:

    INSERT INTO order_current_summary
    SELECT
      merchant_id,
      order_id,
      COUNT(*) AS current_record_count,
      SUM(amount) AS total_amount
    FROM orders
    GROUP BY merchant_id, order_id;
    

    Dalam contoh ini, GROUP BY (merchant_id, order_id) sepenuhnya mencakup kunci primer tabel sumber, dan kunci primer tabel hasil sesuai dengan bidang pengelompokan.

  3. Langkah 3: Verifikasi rencana eksekusi.

    Tinjau rencana eksekusi SQL sebelum mengirimkan penerapan. Keberadaan node DeltaAggregate menunjukkan bahwa Delta Aggregation telah diaktifkan. Contoh:

    DeltaAggregate(
      groupBy=[merchant_id, order_id],
      lookupKeys=[merchant_id, order_id]
    )
    

Tuning opsional

Jalankan penerapan terlebih dahulu dengan pengaturan default. Kemudian sesuaikan parameter individual berdasarkan performa lookup dan throughput penerapan. Tempatkan setiap pernyataan SET berikut sebelum pernyataan INSERT INTO yang sesuai.

Pilih strategi pengaktifan

table.optimizer.delta-agg.strategy mendukung nilai-nilai berikut:

Nilai

Deskripsi

EVENTUAL

Memaksa Delta Aggregation. Jika kueri tidak memenuhi persyaratan, kesalahan akan dikembalikan saat rencana eksekusi dihasilkan.

AUTO

Mencoba menggunakan Delta Aggregation. Jika kueri tidak memenuhi persyaratan, mesin akan kembali ke agregasi kelompok reguler.

NONE

Menonaktifkan Delta Aggregation. Ini adalah nilai default.

Tune parameter lookup asinkron

Gunakan parameter berikut untuk menyesuaikan konkurensi dan timeout lookup asinkron:

SET 'table.exec.async-lookup.buffer-capacity' = '100';
SET 'table.exec.async-lookup.timeout' = '3 min';

Parameter

Default

Deskripsi

table.exec.async-lookup.buffer-capacity

100

Jumlah permintaan lookup asinkron yang dapat dieksekusi secara konkuren oleh setiap subtugas paralel. Tingkatkan nilai ini untuk meningkatkan konkurensi lookup asinkron.

table.exec.async-lookup.timeout

3 min

Periode timeout untuk satu operasi asinkron.

Untuk informasi lebih lanjut tentang tuning lookup asinkron, lihat Pernyataan JOIN tabel dimensi.

Aktifkan miniBatch Delta Aggregation

Baik Delta Aggregation maupun Group Aggregation mendukung optimasi miniBatch. Untuk Delta Aggregation, miniBatch menggabungkan perubahan yang memiliki kunci pengelompokan sama dalam satu batch. Hal ini membatasi setiap kunci pengelompokan menjadi paling banyak satu lookup per batch dan mengurangi jumlah lookup ke tabel sumber.

Gunakan pengaturan berikut untuk mengaktifkan miniBatch untuk Delta Aggregation:

SET 'table.exec.mini-batch.enabled' = 'true';
SET 'table.exec.mini-batch.allow-latency' = '10s';
SET 'table.exec.mini-batch.size' = '1000';

Dengan pengaturan ini, setiap subtugas paralel memicu pemrosesan setelah menerima 1.000 catatan input atau setelah batch menunggu selama 10 detik.

Untuk informasi lebih lanjut tentang optimasi miniBatch dan parameternya, lihat bagian sebelumnya, Aktifkan miniBatch.

Aktifkan cache Delta Aggregation

Jika kunci pengelompokan yang sama diperbarui berulang kali, aktifkan cache untuk menggunakan kembali catatan detail kelompok yang sebelumnya diambil. Saat terjadi hit cache, Flink memperbarui catatan yang di-cache dengan perubahan input dan menghitung ulang hasil agregat secara langsung tanpa melakukan lookup lagi.

Saat cache diaktifkan, tabel sumber harus memiliki kunci primer. Flink menggunakan kunci primer tabel sumber untuk mengidentifikasi dan memperbarui catatan detail dalam cache. table.exec.delta-agg.cache-size harus lebih besar dari 0.

SET 'table.exec.delta-agg.cache-enabled' = 'true';
SET 'table.exec.delta-agg.cache-size' = '2000';

Parameter

Default

Deskripsi

table.exec.delta-agg.cache-enabled

false

Menentukan apakah cache Delta Aggregation diaktifkan.

table.exec.delta-agg.cache-size

10000

Jumlah maksimum kunci pengelompokan yang di-cache oleh setiap subtugas paralel Delta Aggregation. Parameter ini hanya berlaku saat cache diaktifkan.

Longgarkan validasi filter hasil agregat

Delta Aggregation tidak mengirim catatan -U untuk hasil agregat sebelumnya. Pertimbangkan filter hilir HAVING SUM(amount) >= 100. Saat SUM(amount) suatu kelompok berubah dari 120 menjadi 80:

+U(..., 120) → Sesuai kondisi dan ditulis ke tabel hasil
+U(..., 80)  → Tidak sesuai kondisi dan difilter

Karena tidak ada catatan -U yang menarik kembali hasil sebelumnya, catatan SUM(amount)=120 tetap berada di tabel hasil. Untuk mencegah masalah ini, Delta Aggregation mengharuskan filter hilir hanya mereferensikan bidang kunci unik dari hasil agregat, biasanya bidang GROUP BY.

Jika filter mereferensikan bidang non-kunci-unik seperti SUM, strategi EVENTUAL akan mengembalikan kesalahan dan strategi AUTO akan kembali ke agregasi kelompok reguler. Kondisi WHERE sebelum GROUP BY tidak tunduk pada validasi ini.

Jika bisnis Anda dapat mentoleransi perilaku ini, gunakan pengaturan berikut untuk melewati validasi:

SET 'table.optimizer.delta-agg.ignore-non-unique-key-filter' = 'true';

Parameter

Default

Deskripsi

table.optimizer.delta-agg.ignore-non-unique-key-filter

false

Menentukan apakah validasi filter non-kunci-unik pada hasil Delta Aggregation dilewati.

Pengaturan ini hanya melewati validasi. Pengaturan ini tidak mengubah filter dalam pernyataan SQL atau menyebabkan Delta Aggregation menghasilkan catatan -U. Oleh karena itu, Flink tidak mengirim catatan penarikan untuk menghapus hasil usang yang dijelaskan di atas.

Optimalkan join

Pemisahan key-value untuk join dua aliran

Pada VVR 6.0.1 dan versi lebih baru, mesin secara otomatis menyimpulkan apakah akan mengaktifkan pemisahan key-value untuk operator JOIN dua aliran, meningkatkan performa join khas lebih dari 40%.

Konfigurasikan parameter table.exec.join.kv-separate untuk mengontrol perilaku ini:

Nilai Perilaku
AUTO Mesin mengaktifkan pemisahan key-value secara otomatis berdasarkan status operator join. Default.
FORCE Memaksa mengaktifkan pemisahan key-value.
NONE Memaksa menonaktifkan pemisahan key-value.
Catatan

Pemisahan key-value hanya berlaku pada GeminiStateBackend.

Aktifkan miniBatch untuk join

Secara default, operator join reguler memproses catatan satu per satu: mencari status pasangan berdasarkan kunci gabungan, memperbarui status, lalu menghasilkan output. Pola per-catatan ini meningkatkan beban backend status — terutama dengan RocksDB — dan dapat menyebabkan amplifikasi catatan parah pada join bertingkat.

MiniBatch untuk join mengatasi hal ini dengan dua optimasi inti:

  1. Pelipatan catatan: Melipat catatan dalam buffer untuk mengurangi volume data sebelum proses join.

  2. Penekanan output: Menekan hasil antara yang redundan selama pemrosesan batch.

MiniBatch memicu pemrosesan saat latensi maksimum tercapai, batas ukuran batch tercapai, atau terjadi checkpoint.

Versi VVR: 8.0.4 atau lebih baru.

Cara mengaktifkan: Tambahkan konfigurasi berikut ke bidang Other Configuration. Konfigurasikan parameter penerapan kustom.

table.exec.mini-batch.enabled: true
table.exec.mini-batch.allow-latency: 5s
table.exec.stream.join.mini-batch-enabled: true

Paling cocok untuk: Join outer bertingkat dengan amplifikasi pesan. Operator hulu menggunakan collapse atau merge pesan untuk menekan amplifikasi pada operator hilir. Contohnya:

SELECT a.id AS a_id, a.a_content, B.id AS b_id, B.b_content
FROM a LEFT JOIN
  (SELECT * FROM b
      LEFT JOIN c ON b.prd_id = c.id) B
ON a.id = B.id

Optimalkan kueri TopN

Algoritma TopN

Algoritma yang digunakan bergantung pada apakah aliran data masukan bersifat statis atau dinamis:

Jenis input Algoritma yang tersedia Catatan
Aliran data statis (misalnya, dari Simple Log Service) AppendRank Satu-satunya opsi untuk aliran statis.
Aliran data dinamis (misalnya, dari agregasi atau join) UpdateFastRank, RetractRank UpdateFastRank optimal. RetractRank merupakan fallback.

Nama algoritma muncul dalam nama node topologi.

Beralih dari RetractRank ke UpdateFastRank

UpdateFastRank memerlukan semua kondisi berikut:

  1. Aliran input tidak berisi pesan DELETE atau UPDATE_BEFORE. Verifikasi dengan EXPLAIN:

       EXPLAIN CHANGELOG_MODE <query_statement_or_insert_statement_or_statement_set>
  2. Aliran input berisi informasi kunci primer (misalnya, kolom yang digunakan dalam klausa GROUP BY).

  3. Bidang ORDER BY diperbarui secara monotonik dalam urutan kebalikan dari pengurutan. Misalnya, ORDER BY COUNT DESC, ORDER BY COUNT_DISTINCT DESC, atau ORDER BY SUM(nilai positif) DESC.

Contoh: Untuk ORDER BY SUM DESC, filter nilai positif untuk menjamin monotonicity:

INSERT INTO print_test
SELECT
  cate_id,
  seller_id,
  stat_date,
  pay_ord_amt
FROM (
    SELECT
      *,
      ROW_NUMBER() OVER (
        -- Kolom PARTITION BY harus muncul dalam GROUP BY subkueri.
        -- Sertakan bidang waktu untuk mencegah ketidakteraturan saat status kedaluwarsa.
        PARTITION BY cate_id, stat_date
        ORDER BY pay_ord_amt DESC
      ) AS rownum
    FROM (
        SELECT
          cate_id,
          seller_id,
          stat_date,
          -- SUM meningkat secara monotonik karena hanya nilai positif yang disertakan.
          SUM(total_fee) FILTER (WHERE total_fee >= 0) AS pay_ord_amt
        FROM random_test
        WHERE total_fee >= 0
        GROUP BY seller_id, stat_date, cate_id
      ) a
  )
WHERE rownum <= 100;
Catatan

Dalam contoh ini, tabel random_test berisi aliran data statis. Hasil agregasi tidak berisi pesan DELETE atau UPDATE_BEFORE, sehingga monotonicity terjaga.

Kurangi volume output

Jangan sertakan rownum dalam output SELECT akhir. Urutkan hasil di antarmuka depan alih-alih untuk mengurangi volume tulis sink. Top-N.

Tingkatkan ukuran cache TopN

TopN memelihara cache status untuk mengurangi pembacaan disk. Hitung rasio hit cache dengan rumus ini:

cache_hit = cache_size * parallelism / top_n / partition_key_num

Contoh: Dengan Top100, ukuran cache default 10.000 catatan, paralelisme 50, dan 100.000 kunci partisi:

10.000 * 50 / 100 / 100.000 = 5% rasio hit

Rasio hit 5% berarti sebagian besar pembacaan mengakses disk, menyebabkan metrik state seek tidak stabil dan performa menurun. Tingkatkan ukuran cache:

table.exec.rank.topn-cache-size: 200000

Dengan 200.000 entri cache:

200.000 * 50 / 100 / 100.000 = 100% rasio hit

Jika jumlah kunci partisi besar, tingkatkan juga ukuran cache TopN dan memori heap. Konfigurasikan penerapan.

Sertakan bidang waktu dalam PARTITION BY

Tambahkan bidang waktu seperti day ke klausa PARTITION BY. Tanpa itu, hasil TopN menjadi tidak teratur saat data status kedaluwarsa karena TTL.

Deduplikasi secara efisien

Aliran input sering kali berisi duplikat. Realtime Compute for Apache Flink menyediakan dua kebijakan deduplikasi:

  • Deduplicate Keep FirstRow: Menyimpan catatan paling awal per kunci.

  • Deduplicate Keep LastRow: Menyimpan catatan paling akhir per kunci.

Sintaks

Deduplikasi merupakan kasus khusus TopN. Gunakan ROW_NUMBER() dengan klausa OVER untuk memberikan nomor baris per partisi, lalu simpan hanya rownum = 1:

SELECT *
FROM (
   SELECT *,
    ROW_NUMBER() OVER (PARTITION BY col1[, col2..]
     ORDER BY timeAttributeCol [ASC|DESC]) AS rownum
   FROM table_name)
WHERE rownum = 1
Elemen Deskripsi
ROW_NUMBER() Memberikan nomor baris mulai dari 1 dalam setiap partisi.
PARTITION BY col1[, col2..] Kolom yang mendefinisikan kunci deduplikasi.
ORDER BY timeAttributeCol Kolom atribut waktu (proctime atau rowtime). ASC menyimpan baris pertama (Keep FirstRow). DESC menyimpan baris terakhir (Keep LastRow).
rownum = 1 Hanya menyimpan baris pertama per partisi. Juga mendukung rownum <= 1.

Perilaku atribut waktu:

  • proctime (waktu pemrosesan): Deduplikasi berdasarkan kapan catatan diproses. Hasil dapat berbeda antar eksekusi.

  • rowtime (waktu event): Deduplikasi berdasarkan kapan catatan diproduksi. Hasil deterministik.

Keep FirstRow

Menyimpan catatan pertama per kunci deduplikasi. Status hanya menyimpan data kunci primer, sehingga akses status sangat efisien.

SELECT *
FROM (
  SELECT *,
    ROW_NUMBER() OVER (PARTITION BY b ORDER BY proctime) AS rowNum
  FROM T
)
WHERE rowNum = 1

Menghapus data duplikat dari tabel T berdasarkan kolom b, dengan mempertahankan catatan paling awal berdasarkan waktu pemrosesan. Alih-alih mendeklarasikan atribut proctime, gunakan fungsi PROCTIME().

Keep LastRow

Menyimpan catatan paling baru per kunci deduplikasi. Performanya sedikit lebih baik daripada fungsi LAST_VALUE.

SELECT *
FROM (
  SELECT *,
    ROW_NUMBER() OVER (PARTITION BY b, d ORDER BY rowtime DESC) AS rowNum
  FROM T
)
WHERE rowNum = 1

Mendeduplikasi tabel T berdasarkan kolom b dan d, dengan mempertahankan catatan terbaru berdasarkan waktu event.

Gunakan fungsi bawaan secara efisien

Utamakan fungsi bawaan daripada UDF

Fungsi bawaan dioptimalkan untuk serialisasi, deserialisasi, dan operasi tingkat byte. Ganti UDF dengan padanan bawaan bila memungkinkan.

Gunakan delimiter karakter tunggal dalam KEYVALUE

Fungsi KEYVALUE(content, keyValueSplit, keySplit, keyName) berjalan sekitar 30% lebih cepat saat keyValueSplit dan keySplit berupa karakter tunggal seperti : atau ,. Dengan delimiter karakter tunggal, mesin mencari kunci target langsung dalam data biner tanpa menguraikan seluruh input.

Pola operator LIKE

Pola Kecocokan Contoh
LIKE 'xxx%' Diawali dengan xxx LIKE 'order%'
LIKE '%xxx' Diakhiri dengan xxx LIKE '%_id'
LIKE '%xxx%' Berisi xxx LIKE '%error%'
LIKE 'xxx' Cocok persis (setara dengan = 'xxx') LIKE 'active'

Escape underscore: Karakter underscore (_) merupakan wildcard karakter tunggal dalam SQL. Untuk mencocokkan underscore literal, gunakan karakter escape:

LIKE '%seller/_id%' ESCAPE '/'

Tanpa escaping, LIKE '%seller_id%' juga akan mencocokkan seller#id, sellerxid, seller1id, dan string lain yang tidak diinginkan.

Hindari ekspresi reguler

Ekspresi reguler bisa 100x lebih lambat daripada operasi aritmetika dan dapat masuk ke loop tak hingga dalam kasus tepi, sehingga menghentikan penerapan. Gunakan LIKE jika memungkinkan.

Untuk kasus yang memerlukan ekspresi reguler, lihat REGEXP dan REGEXP_REPLACE.

Petunjuk SQL

Petunjuk SQL memengaruhi rencana eksekusi pengoptimal, melampirkan metadata atau statistik, serta mengonfigurasi Opsi Tabel Dinamis berbasis per-tabel. Petunjuk SQL.

Sintaks

Sintaks mengikuti Apache Calcite SQL:

SELECT /*+ hint [, hint ] */ ...

-- Where:
-- hint:       hintName(hintOption [, hintOption]*)
-- hintOption:  simpleIdentifier | numericLiteral | stringLiteral

Petunjuk join

Petunjuk kueri memodifikasi rencana eksekusi dalam blok kueri saat ini. Flink saat ini hanya mendukung petunjuk join, baik untuk join tabel dimensi maupun join reguler.