Jika dua tabel yang ingin digabungkan mengandung nilai kunci panas, masalah ekor panjang dapat terjadi. Anda dapat mengekstrak nilai kunci panas dari kedua tabel, menghitung hasil penggabungan nilai kunci panas dan non-kunci panas secara terpisah, lalu menggabungkan data yang telah dihitung. PETUNJUK SKEWJOIN dapat digunakan untuk mengekstrak nilai kunci panas secara otomatis atau manual, menghitung hasil penggabungan nilai kunci panas dan non-kunci panas secara terpisah, serta menggabungkan data yang telah dihitung. Dengan cara ini, operasi JOIN dipercepat.
Penggunaan
PETUNJUK SKEWJOIN hanya dapat digunakan setelah menambahkan petunjuk penggabungan miring /*+ skewJoin(<table_name>[(<column1_name>[,<column2_name>,...])][((<value11>,<value12>)[,(<value21>,<value22>)...])]*/ ke dalam pernyataan SELECT. Dalam petunjuk ini, table_name adalah nama tabel miring, column_name adalah nama kolom miring, dan value adalah nilai kunci miring.
-- Metode 1: Sertakan alias tabel dalam PETUNJUK SKEWJOIN.
select /*+ skewjoin(a) */ * from T0 a join T1 b on a.c0 = b.c0 and a.c1 = b.c1;
-- Metode 2: Tambahkan petunjuk untuk menentukan nama tabel dan nama kolom yang mungkin miring. Sebagai contoh, pernyataan berikut menunjukkan bahwa Kolom c0 dan c1 di Tabel a adalah kolom miring.
select /*+ skewjoin(a(c0, c1)) */ * from T0 a join T1 b on a.c0 = b.c0 and a.c1 = b.c1 and a.c2 = b.c2;
-- Metode 3: Tambahkan petunjuk untuk menentukan nama tabel dan nama kolom serta menyediakan nilai kunci miring. Jika nilai kunci miring bertipe STRING, sertakan setiap nilai dengan tanda kutip ganda ("). Dalam pernyataan berikut, (a.c0=1 dan a.c1="2") dan (a.c0=3 dan a.c1="4") berisi nilai kunci miring.
select /*+ skewjoin(a(c0, c1)((1, "2"), (3, "4"))) */ * from T0 a join T1 b on a.c0 = b.c0 and a.c1 = b.c1 and a.c2 = b.c2;Metode 3 lebih efisien dibandingkan Metode 1 dan Metode 2.
Implementasi
Nilai kunci panas adalah nilai kunci yang sering muncul dalam sebuah tabel. Pada gambar berikut, bagian merah memiliki 10.000 catatan dengan a.c0=1 dan a.c1=2 dan 9.000 catatan dengan a.c0=3 dan a.c1=4.
Jika PETUNJUK SKEWJOIN tidak digunakan dan tabel T0 dan T1 berisi sejumlah besar data, hanya pernyataan MERGE JOIN yang dapat dieksekusi pada kedua tabel tersebut. Dalam hal ini, nilai kunci panas yang sama dikocok ke satu node tunggal, menyebabkan kemiringan data. Setelah menggunakan PETUNJUK SKEWJOIN, optimizer menjalankan Aggregate untuk mendapatkan 20 nilai kunci panas teratas secara dinamis berdasarkan jumlah rekornya. Optimizer secara terpisah mengekstrak nilai kunci panas (data A) dan nilai non-kunci panas (data B) dari tabel T0, serta mengekstrak nilai (data C) yang dapat digabungkan dengan data A dan nilai (data D) yang tidak dapat digabungkan dengan data A dari tabel T1. Kemudian, pernyataan MAP JOIN dijalankan pada data A dan data C (volume data kecil), sementara pernyataan MERGE JOIN dijalankan pada data B dan data D. Hasil dari pernyataan MAP JOIN dan MERGE JOIN digabungkan menggunakan pernyataan UNION untuk menghasilkan hasil akhir, seperti yang ditunjukkan pada gambar berikut.
Peringatan
Saat menggunakan PETUNJUK SKEWJOIN untuk pernyataan JOIN, perhatikan batasan berikut:
INNER JOIN: Petunjuk penggabungan miring dapat ditentukan untuk tabel kiri atau kanan dalam pernyataan INNER JOIN.
LEFT JOIN, SEMI JOIN, dan ANTI JOIN: Petunjuk penggabungan miring hanya dapat ditentukan untuk tabel kiri.
RIGHT JOIN: Petunjuk penggabungan miring hanya dapat ditentukan untuk tabel kanan.
FULL JOIN: Petunjuk penggabungan miring tidak didukung.
Aggregate dijalankan setelah petunjuk penggabungan miring ditambahkan, yang memperlambat operasi penggabungan. Oleh karena itu, disarankan untuk hanya menambahkan petunjuk penggabungan miring ke pernyataan JOIN yang menyebabkan kemiringan data. Jika petunjuk penggabungan miring ditambahkan ke kueri A JOIN B untuk Tabel A, rencana eksekusi fisik serupa dengan
MapJoin union all MergeJoindipaksakan untuk dibuat. Subplan MAPJOIN yang diperluas serupa dengan:Top 20(A) MapJoin (B Semi Join Top20(A)). Jika Tabel B masih berisi sejumlah besar data setelah difilter menggunakanTop20(A), kesalahan kehabisan memori (OOM) mungkin terjadi saat menggunakan MAPJOIN untuk membuat hash join dan tabel hash.Tipe data Kunci Gabungan Sisi Kiri harus sama dengan tipe data Kunci Gabungan Sisi Kanan untuk pernyataan JOIN tempat PETUNJUK SKEWJOIN ditambahkan. Jika tipe data berbeda, PETUNJUK SKEWJOIN menjadi tidak efektif. Dalam contoh sebelumnya, tipe data a.c0 dan b.c0 harus sama, serta tipe data a.c1 dan b.c1 harus sama. Untuk memastikan konsistensi tipe data, gunakan fungsi CAST untuk mengonversi kunci penggabungan dalam subquery. Kode berikut menunjukkan contohnya:
create table T0(c0 int, c1 int, c2 int, c3 int); create table T1(c0 string, c1 int, c2 int); -- Metode 1: select /*+ skewjoin(a) */ * from T0 a join T1 b on cast(a.c0 as string) = cast(b.c0 as string) and a.c1 = b.c1; -- Metode 2: select /*+ skewjoin(b) */ * from (select cast(a.c0 as string) as c00 from T0 a) b join T1 c on b.c00 = c.c0;Setelah petunjuk penggabungan miring ditambahkan, optimizer menjalankan Aggregate untuk mendapatkan N nilai kunci panas pertama. Anda dapat menjalankan perintah
set odps.optimizer.skew.join.topk.num = xx;untuk menentukan jumlah nilai kunci panas yang dapat diperoleh oleh optimizer.Petunjuk penggabungan miring memungkinkan Anda menambahkan petunjuk hanya untuk tabel kiri atau kanan yang terlibat dalam pernyataan JOIN.
Dalam pernyataan JOIN tempat PETUNJUK SKEWJOIN ditambahkan,
left key = right keyharus disertakan. PETUNJUK SKEWJOIN tidak dapat ditambahkan ke pernyataan CARTESIAN JOIN.Pernyataan berikut menunjukkan cara menggunakan PETUNJUK SKEWJOIN dengan petunjuk lainnya. Perhatikan bahwa PETUNJUK SKEWJOIN tidak dapat ditambahkan ke pernyataan JOIN tempat PETUNJUK MAPJOIN ditambahkan.
select /*+ mapjoin(c), skewjoin(a) */ * from T0 a join T1 b on a.c0 = b.c3 join T2 c on a.c0 = c.c7;Di tab Json Summary LogView, Anda dapat mencari bidang topk_agg. Jika bidang tersebut ada, seperti yang ditunjukkan pada gambar berikut, PETUNJUK SKEWJOIN telah berlaku.
