全部产品
Search
文档中心

MaxCompute:Pengoptimal

更新时间:Jul 06, 2025

MaxCompute menggunakan pengoptimal berbasis biaya untuk memperkirakan biaya setiap rencana eksekusi secara akurat, berdasarkan metadata seperti jumlah baris dan panjang rata-rata string. Topik ini menjelaskan cara mengumpulkan metadata yang diperlukan agar pengoptimal dapat meningkatkan kinerja kueri.

Informasi latar belakang

Jika pengoptimal memperkirakan biaya berdasarkan metadata yang tidak akurat, hasil estimasi akan menjadi tidak akurat dan menghasilkan rencana eksekusi yang buruk. Oleh karena itu, metadata yang akurat sangat penting bagi pengoptimal. Metadata inti dari sebuah tabel adalah statistik kolom dalam tabel tersebut, sementara metadata lainnya diperkirakan berdasarkan statistik kolom.

MaxCompute menyediakan metode berikut untuk mengumpulkan statistik kolom:

  • Analyze: Metode pengumpulan asinkron. Anda dapat menjalankan perintah analyze untuk mengumpulkan statistik kolom secara asinkron. Pengumpulan aktif diperlukan.

    Catatan

    Versi klien MaxCompute harus lebih baru dari 0.35.

  • Freeride: Metode pengumpulan sinkron. Saat data dihasilkan dalam tabel, statistik kolom dikumpulkan secara otomatis. Metode ini otomatis tetapi dapat memengaruhi latensi kueri.

Tabel berikut mencantumkan statistik kolom yang dapat dikumpulkan untuk berbagai tipe data.

Metrik statistik kolom/Tipe data

Numerik (TINYINT, SMALLINT, INT, BIGINT, DOUBLE, DECIMAL, dan NUMERIC)

Karakter (STRING, VARCHAR, dan CHAR)

Biner (BINARY)

Boolean (BOOLEAN)

Tanggal dan waktu (TIMESTAMP, DATE, dan INTERVAL)

Tipe data kompleks (MAP, STRUCT, dan ARRAY)

min (nilai minimum)

Y

N

N

N

Y

N

max (nilai maksimum)

Y

N

N

N

Y

N

nNulls (jumlah nilai null)

Y

Y

Y

Y

Y

Y

avgColLen (panjang kolom rata-rata)

N

Y

Y

N

N

N

maxColLen (panjang kolom maksimum)

N

Y

Y

N

N

N

ndv (jumlah nilai unik)

Y

Y

Y

Y

Y

N

topK (nilai K teratas dengan frekuensi kemunculan tertinggi)

Y

Y

Y

Y

Y

N

Catatan

Y menunjukkan bahwa metrik didukung. N menunjukkan bahwa metrik tidak didukung.

Skenario

Tabel berikut menjelaskan skenario penggunaan setiap statistik kolom.

Statistik Kolom

Tujuan Optimasi

Skenario

Deskripsi

min (nilai minimum) atau max (nilai maksimum)

Meningkatkan akurasi optimasi performa.

Skenario 1: Perkirakan jumlah rekaman keluaran.

Jika hanya tipe data yang disediakan, rentang nilainya terlalu besar untuk pengoptimal. Jika nilai min dan max disediakan, pengoptimal dapat lebih akurat memperkirakan pemilihan kondisi filter dan memberikan rencana eksekusi yang lebih baik.

Skema 2: Dorong kondisi filter ke lapisan penyimpanan untuk mengurangi jumlah data yang perlu dibaca.

Dalam MaxCompute, kondisi filter a < -90 dapat didorong ke lapisan penyimpanan, sedangkan kondisi filter a + 100 < 10 tidak dapat didorong. Jika overflow a dipertimbangkan, kedua kondisi filter tidak setara. Namun, jika a memiliki nilai maksimum, kondisi filter setara dan dapat diubah satu sama lain. Oleh karena itu, statistik min dan max memungkinkan lebih banyak kondisi filter didorong ke bawah, mengurangi jumlah data yang perlu dibaca dan biaya.

nNulls (jumlah nilai null)

Meningkatkan efisiensi pemeriksaan nilai null.

Skema 1: Kurangi pemeriksaan nilai null saat pekerjaan dijalankan.

Saat pekerjaan dijalankan, nilai null harus diperiksa untuk semua jenis data. Jika nilai statistik nNulls adalah 0, logika pemeriksaan dapat diabaikan, meningkatkan performa komputasi.

Skema 2: Filter data berdasarkan kondisi filter.

Jika kolom hanya memiliki nilai null, pengoptimal menggunakan kondisi filter always false untuk menyaring data di seluruh kolom, meningkatkan efisiensi penyaringan data.

avgColLen (panjang kolom rata-rata) atau maxColLen (panjang kolom maksimum)

Perkirakan konsumsi sumber daya untuk mengurangi operasi shuffle.

Skema 1: Perkirakan memori tabel terkluster hash.

Sebagai contoh, pengoptimal dapat memperkirakan penggunaan memori bidang panjang variabel berdasarkan statistik avgColLen untuk mendapatkan penggunaan memori rekaman data. Dengan cara ini, pengoptimal dapat secara selektif melakukan operasi map join otomatis. Mekanisme join broadcast didirikan untuk tabel terkluster hash untuk mengurangi operasi shuffle. Untuk tabel input besar, operasi shuffle dapat dikurangi secara signifikan untuk meningkatkan performa.

Skema 2: Kurangi jumlah data yang perlu di-shuffle.

Tidak ada.

ndv (jumlah nilai unik)

Meningkatkan kualitas rencana eksekusi.

Skema 1: Perkirakan jumlah rekaman keluaran operasi join.

  • Ekspansi data: Jika nilai statistik ndv untuk kunci join kedua tabel jauh lebih kecil daripada jumlah baris, sejumlah besar rekaman data adalah duplikat. Dalam hal ini, ekspansi data mungkin terjadi. Pengoptimal dapat mengambil langkah-langkah relevan untuk mencegah masalah yang disebabkan oleh ekspansi data.

  • Penyaringan data: Jika ndv tabel kecil jauh lebih kecil daripada ndv tabel besar, sejumlah besar data dalam tabel besar disaring setelah operasi join. Pengoptimal dapat membuat keputusan optimasi yang relevan berdasarkan hasil perbandingan.

Skema 2: Urutkan operasi join.

Pengoptimal dapat secara otomatis menyesuaikan urutan join berdasarkan perkiraan jumlah rekaman keluaran. Sebagai contoh, ia dapat memindahkan operasi join yang melibatkan penyaringan data ke depan dan operasi join yang melibatkan ekspansi data ke belakang.

topK (nilai K teratas dengan frekuensi kemunculan tertinggi)

Perkirakan distribusi data untuk mengurangi dampak skew data pada performa.

Skema 1: Optimalkan operasi join yang melibatkan data skew.

Jika kedua tabel operasi join memiliki input besar dan operasi map join tidak dapat digunakan untuk sepenuhnya memuat tabel yang lebih kecil ke memori, skew data terjadi. Output satu kunci join jauh lebih besar daripada output kunci join lainnya. MaxCompute dapat secara otomatis menggunakan operasi map join untuk memproses data skew dan menggunakan operasi merge join untuk memproses data non-skew, lalu menggabungkan hasil komputasi. Fitur ini sangat efektif untuk operasi join yang melibatkan sejumlah besar data, mengurangi biaya pemecahan masalah manual.

Skema 2: Perkirakan jumlah rekaman keluaran.

Statistik ndv, min, dan max dapat digunakan untuk memperkirakan jumlah rekaman keluaran secara akurat hanya jika asumsi bahwa data didistribusikan secara merata benar. Jika data jelas skew, estimasi berdasarkan asumsi ini menjadi terdistorsi. Oleh karena itu, pemrosesan khusus diperlukan untuk data skew. Data lainnya dapat diperkirakan berdasarkan asumsi.

Gunakan Analyze

Kumpulkan metrik statistik kolom

Bagian ini menggunakan tabel terpartisi dan tabel non-partisi sebagai contoh untuk menjelaskan cara menggunakan Analyze.

  • Tabel non-partisi

    Anda dapat menggunakan Analyze untuk mengumpulkan statistik kolom satu atau beberapa kolom tertentu atau semua kolom dalam tabel non-partisi.

    1. Jalankan perintah berikut pada klien MaxCompute untuk membuat tabel non-partisi bernama analyze2_test:

      create table if not exists analyze2_test (tinyint1 tinyint, smallint1 smallint, int1 int, bigint1 bigint, double1 double, decimal1 decimal, decimal2 decimal(20,10), string1 string, varchar1 varchar(10), boolean1 boolean, timestamp1 timestamp, datetime1 datetime ) lifecycle 30;
    2. Jalankan perintah berikut untuk menyisipkan data ke dalam tabel:

      insert overwrite table analyze2_test select * from values (1Y, 20S, 4, 8L, 123452.3, 12.4, 52.5, 'str1', 'str21', false, timestamp '2018-09-17 00:00:00', datetime '2018-09-17 00:59:59') ,(10Y, 2S, 7, 11111118L, 67892.3, 22.4, 42.5, 'str12', 'str200', true, timestamp '2018-09-17 00:00:00', datetime '2018-09-16 00:59:59') ,(20Y, 7S, 4, 2222228L, 12.3, 2.4, 2.57, 'str123', 'str2', false, timestamp '2018-09-18 00:00:00', datetime '2018-09-17 00:59:59') ,(null, null, null, null, null, null, null, null, null, null, null , null) as t(tinyint1, smallint1, int1, bigint1, double1, decimal1, decimal2, string1, varchar1, boolean1, timestamp1, datetime1);
    3. Jalankan perintah analyze untuk mengumpulkan statistik kolom satu atau beberapa kolom tertentu atau semua kolom dalam tabel. Contoh:

      -- Kumpulkan metrik statistik kolom tinyint1.
      analyze table analyze2_test compute statistics for columns (tinyint1);
      
      -- Kumpulkan metrik statistik kolom smallint1, string1, boolean1, dan timestamp1.
      analyze table analyze2_test compute statistics for columns (smallint1, string1, boolean1, timestamp1);
      
      -- Kumpulkan metrik statistik semua kolom.
      analyze table analyze2_test compute statistics for columns;
    4. Jalankan perintah show statistic untuk menguji hasil pengumpulan. Contoh:

      -- Uji hasil pengumpulan kolom tinyint1.
      show statistic analyze2_test columns (tinyint1);
      
      -- Uji hasil pengumpulan kolom smallint1, string1, boolean1, dan timestamp1.
      show statistic analyze2_test columns (smallint1, string1, boolean1, timestamp1);
      
      -- Uji hasil pengumpulan semua kolom.
      show statistic analyze2_test columns;

      Hasil berikut dikembalikan:

      -- Hasil pengumpulan kolom tinyint1:
      ID = 20201126085225150gnqo****
      tinyint1:MaxValue:      20                   -- Nilai max.
      tinyint1:DistinctNum:   4.0                  -- Nilai ndv.
      tinyint1:MinValue:      1                    -- Nilai min.
      tinyint1:NullNum:       1.0                  -- Nilai nNulls.
      tinyint1:TopK:  {1=1.0, 10=1.0, 20=1.0}      -- Nilai topK. 10=1.0 menunjukkan bahwa frekuensi kemunculan nilai kolom 10 adalah 1. Hingga 20 nilai dengan frekuensi kemunculan tertinggi dapat dikembalikan.
      
      -- Hasil pengumpulan kolom smallint1, string1, boolean1, dan timestamp1:
      ID = 20201126091636149gxgf****
      smallint1:MaxValue:     20
      smallint1:DistinctNum:  4.0
      smallint1:MinValue:     2
      smallint1:NullNum:      1.0
      smallint1:TopK:         {2=1.0, 7=1.0, 20=1.0}
      
      string1:MaxLength       6.0                  -- Nilai maxColLen.
      string1:AvgLength:      3.0                  -- Nilai avgColLen.
      string1:DistinctNum:    4.0
      string1:NullNum:        1.0
      string1:TopK:   {str1=1.0, str12=1.0, str123=1.0}
      
      boolean1:DistinctNum:   3.0
      boolean1:NullNum:       1.0
      boolean1:TopK:  {false=2.0, true=1.0}
      
      timestamp1:DistinctNum:         3.0
      timestamp1:NullNum:     1.0
      timestamp1:TopK:        {2018-09-17 00:00:00.0=2.0, 2018-09-18 00:00:00.0=1.0}
      
      -- Hasil pengumpulan semua kolom:
      ID = 20201126092022636gzm1****
      tinyint1:MaxValue:      20
      tinyint1:DistinctNum:   4.0
      tinyint1:MinValue:      1
      tinyint1:NullNum:       1.0
      tinyint1:TopK:  {1=1.0, 10=1.0, 20=1.0}
      
      smallint1:MaxValue:     20
      smallint1:DistinctNum:  4.0
      smallint1:MinValue:     2
      smallint1:NullNum:      1.0
      smallint1:TopK:         {2=1.0, 7=1.0, 20=1.0}
      
      int1:MaxValue:  7
      int1:DistinctNum:       3.0
      int1:MinValue:  4
      int1:NullNum:   1.0
      int1:TopK:      {4=2.0, 7=1.0}
      
      bigint1:MaxValue:       11111118
      bigint1:DistinctNum:    4.0
      bigint1:MinValue:       8
      bigint1:NullNum:        1.0
      bigint1:TopK:   {8=1.0, 2222228=1.0, 11111118=1.0}
      
      double1:MaxValue:       123452.3
      double1:DistinctNum:    4.0
      double1:MinValue:       12.3
      double1:NullNum:        1.0
      double1:TopK:   {12.3=1.0, 67892.3=1.0, 123452.3=1.0}
      
      decimal1:MaxValue:      22.4
      decimal1:DistinctNum:   4.0
      decimal1:MinValue:      2.4
      decimal1:NullNum:       1.0
      decimal1:TopK:  {2.4=1.0, 12.4=1.0, 22.4=1.0}
      
      decimal2:MaxValue:      52.5
      decimal2:DistinctNum:   4.0
      decimal2:MinValue:      2.57
      decimal2:NullNum:       1.0
      decimal2:TopK:  {2.57=1.0, 42.5=1.0, 52.5=1.0}
      
      string1:MaxLength       6.0
      string1:AvgLength:      3.0
      string1:DistinctNum:    4.0
      string1:NullNum:        1.0
      string1:TopK:   {str1=1.0, str12=1.0, str123=1.0}
      
      varchar1:MaxLength      6.0
      varchar1:AvgLength:     3.0
      varchar1:DistinctNum:   4.0
      varchar1:NullNum:       1.0
      varchar1:TopK:  {str2=1.0, str200=1.0, str21=1.0}
      
      boolean1:DistinctNum:   3.0
      boolean1:NullNum:       1.0
      boolean1:TopK:  {false=2.0, true=1.0}
      
      timestamp1:DistinctNum:         3.0
      timestamp1:NullNum:     1.0
      timestamp1:TopK:        {2018-09-17 00:00:00.0=2.0, 2018-09-18 00:00:00.0=1.0}
      
      datetime1:DistinctNum:  3.0
      datetime1:NullNum:      1.0
      datetime1:TopK:         {1537117199000=2.0, 1537030799000=1.0}
  • Tabel terpartisi

    Anda dapat menggunakan Analyze untuk mengumpulkan statistik kolom partisi tertentu dalam tabel terpartisi.

    1. Jalankan perintah berikut pada klien MaxCompute untuk membuat tabel terpartisi bernama srcpart:

      create table if not exists srcpart_test (key string, value string) partitioned by (ds string, hr string) lifecycle 30;
    2. Jalankan perintah berikut untuk menyisipkan data ke dalam tabel:

      insert into table srcpart_test partition(ds='20201220', hr='11') values ('123', 'val_123'), ('76', 'val_76'), ('447', 'val_447'), ('1234', 'val_1234');
      insert into table srcpart_test partition(ds='20201220', hr='12') values ('3', 'val_3'), ('12331', 'val_12331'), ('42', 'val_42'), ('12', 'val_12');
      insert into table srcpart_test partition(ds='20201221', hr='11') values ('543', 'val_543'), ('2', 'val_2'), ('4', 'val_4'), ('9', 'val_9');
      insert into table srcpart_test partition(ds='20201221', hr='12') values ('23', 'val_23'), ('56', 'val_56'), ('4111', 'val_4111'), ('12333', 'val_12333');
    3. Jalankan perintah analyze untuk mengumpulkan statistik kolom partisi tertentu dalam tabel. Contoh:

      analyze table srcpart_test partition(ds='20201221') compute statistics for columns (key , value);
    4. Jalankan perintah show statistic untuk menguji hasil pengumpulan. Contoh:

      show statistic srcpart_test partition (ds='20201221') columns (key , value);

      Hasil berikut dikembalikan:

      ID = 20210105121800689g28p****
      (ds=20201221,hr=11) key:MaxLength       3.0
      (ds=20201221,hr=11) key:AvgLength:      1.0
      (ds=20201221,hr=11) key:DistinctNum:    4.0
      (ds=20201221,hr=11) key:NullNum:        0.0
      (ds=20201221,hr=11) key:TopK:   {2=1.0, 4=1.0, 543=1.0, 9=1.0}
      
      (ds=20201221,hr=11) value:MaxLength     7.0
      (ds=20201221,hr=11) value:AvgLength:    5.0
      (ds=20201221,hr=11) value:DistinctNum:  4.0
      (ds=20201221,hr=11) value:NullNum:      0.0
      (ds=20201221,hr=11) value:TopK:         {val_2=1.0, val_4=1.0, val_543=1.0, val_9=1.0}
      
      (ds=20201221,hr=12) key:MaxLength       5.0
      (ds=20201221,hr=12) key:AvgLength:      3.0
      (ds=20201221,hr=12) key:DistinctNum:    4.0
      (ds=20201221,hr=12) key:NullNum:        0.0
      (ds=20201221,hr=12) key:TopK:   {12333=1.0, 23=1.0, 4111=1.0, 56=1.0}
      
      (ds=20201221,hr=12) value:MaxLength     9.0
      (ds=20201221,hr=12) value:AvgLength:    7.0
      (ds=20201221,hr=12) value:DistinctNum:  4.0
      (ds=20201221,hr=12) value:NullNum:      0.0
      (ds=20201221,hr=12) value:TopK:         {val_12333=1.0, val_23=1.0, val_4111=1.0, val_56=1.0}

Perbarui jumlah rekaman dalam tabel di metadata

Berbagai tugas di MaxCompute dapat memengaruhi jumlah rekaman dalam tabel. Sebagian besar tugas hanya mengumpulkan jumlah rekaman yang terpengaruh oleh tugas itu sendiri. Statistik jumlah rekaman yang terpengaruh oleh tugas mungkin tidak akurat karena sifat dinamis dari tugas terdistribusi dan ketidakpastian waktu pembaruan data. Oleh karena itu, Anda dapat menjalankan perintah Analyze untuk memperbarui statistik jumlah rekaman dalam tabel di metadata, memastikan keakuratan jumlah rekaman. Anda dapat melihat jumlah rekaman dalam tabel di DataMap DataWorks. Untuk informasi lebih lanjut, lihat Lihat detail tabel.

  • Perbarui jumlah rekaman dalam tabel.

    set odps.sql.analyze.table.stats=only; 
    analyze table <table_name> compute statistics for columns;  

    Parameter table_name menentukan nama tabel.

  • Perbarui jumlah rekaman dalam kolom tabel.

    set odps.sql.analyze.table.stats=only; 
    analyze table <table_name> compute statistics for columns (<column_name>);

    Parameter table_name menentukan nama tabel. Parameter column_name menentukan nama kolom.

  • Perbarui jumlah rekaman dalam kolom partisi tabel.

    set odps.sql.analyze.table.stats=only; 
    analyze table <table_name> partition(<pt_spec>) compute statistics for columns (<column_name>);

    Parameter table_name menentukan nama tabel. Parameter pt_spec menentukan partisi. Parameter column_name menentukan nama kolom.

Gunakan Freeride

Untuk menggunakan Freeride, Anda harus menjalankan perintah berikut pada tingkat sesi secara bersamaan untuk mengonfigurasi properti:

  • set odps.optimizer.stat.collect.auto=true;: Aktifkan Freeride untuk secara otomatis mengumpulkan statistik kolom tabel.

  • set odps.optimizer.stat.collect.plan=xx;: Konfigurasikan rencana pengumpulan untuk mengumpulkan statistik kolom tertentu dari kolom tertentu.

    -- Kumpulkan metrik avgColLen kolom key dalam tabel target_table.
    set odps.optimizer.stat.collect.plan={"target_table":"{\"key\":\"AVG_COL_LEN\"}"}
    
    -- Kumpulkan metrik min dan max kolom s_binary dalam tabel target_table, dan metrik topK dan nNulls kolom s_int dalam tabel.
    set odps.optimizer.stat.collect.plan={"target_table":"{\"s_binary\":\"MIN,MAX\",\"s_int\":\"TOPK,NULLS\"}"};
Catatan

Jika tidak ada data yang dikumpulkan setelah perintah dijalankan, Freeride mungkin gagal diaktifkan. Anda perlu memeriksa apakah properti odps.optimizer.stat.collect.auto dapat ditemukan di tab Json Summary LogView. Jika properti ini tidak ditemukan, versi server saat ini tidak mendukung Freeride. Server akan ditingkatkan ke versi yang mendukung Freeride di masa mendatang.

Pemetaan antara statistik kolom dan parameter dalam perintah set odps.optimizer.stat.collect.plan=xx;:

  • min: MIN

  • max: MAX

  • nNulls: NULLS

  • avgColLen: AVG_COL_LEN

  • maxColLen: MAX_COL_LEN

  • ndv: NDV

  • topK: TOPK

MaxCompute memungkinkan Anda mengeksekusi pernyataan CREATE TABLE, INSERT INTO, atau INSERT OVERWRITE untuk memicu Freeride mengumpulkan statistik kolom.

Sebelum menggunakan Freeride, Anda harus menyiapkan tabel sumber. Sebagai contoh, jalankan perintah berikut untuk membuat tabel sumber bernama src_test dan menyisipkan data ke dalam tabel:

create table if not exists src_test (key string, value string);
insert overwrite table src_test values ('100', 'val_100'), ('100', 'val_50'), ('200', 'val_200'), ('200', 'val_300');
  • CREATE TABLE: Gunakan Freeride untuk mengumpulkan statistikkolom saat Anda membuat tabel tujuan bernama target. Contoh pernyataan:

    -- Buat tabel tujuan.
    set odps.optimizer.stat.collect.auto=true;
    set odps.optimizer.stat.collect.plan={"target_test":"{\"key\":\"AVG_COL_LEN,NULLS\"}"};
    create table target_test as select key, value from src_test;
    -- Uji hasil pengumpulan.
    show statistic target_test columns;

    Hasil berikut dikembalikan:

    key:AvgLength: 3.0
    key:NullNum:  0.0
  • INSERT INTO: Gunakan Freeride untuk mengumpulkan statistik kolom saat Anda mengeksekusi pernyataan INSERT INTO untuk menambahkan data ke tabel. Contoh pernyataan:

    -- Buat tabel tujuan.
    create table freeride_insert_into_table like src_test;
    -- Tambahkan data ke tabel.
    set odps.optimizer.stat.collect.auto=true;
    set odps.optimizer.stat.collect.plan={"freeride_insert_into_table":"{\"key\":\"AVG_COL_LEN,NULLS\"}"};
    insert into table freeride_insert_into_table select key, value from src order by key, value limit 10;
    -- Uji hasil pengumpulan.
    show statistic freeride_insert_into_table columns;
  • INSERT OVERWRITE: Gunakan Freeride untuk mengumpulkan statistik kolom saat Anda mengeksekusi pernyataan INSERT OVERWRITE untuk menimpa data dalam tabel. Contoh pernyataan:

    -- Buat tabel tujuan.
    create table freeride_insert_overwrite_table like src_test;
    -- Timpa data dalam tabel.
    set odps.optimizer.stat.collect.auto=true;
    set odps.optimizer.stat.collect.plan={"freeride_insert_overwrite_table":"{\"key\":\"AVG_COL_LEN,NULLS\"}"};
    insert overwrite table freeride_insert_overwrite_table select key, value from src_test order by key, value limit 10;
    -- Uji hasil pengumpulan.
    show statistic freeride_insert_overwrite_table columns;