Eksekusi kueri adaptif
Eksekusi kueri adaptif (AQE) adalah pengoptimalan ulang kueri yang terjadi selama eksekusi kueri.
Motivasi untuk pengoptimalan ulang runtime bahasa umum adalah bahwa Azure Databricks memiliki statistik akurat terbaru di akhir pertukaran acak dan siaran (disebut sebagai tahap kueri di AQE). Akibatnya, Azure Databricks dapat memilih strategi fisik yang lebih baik, memilih ukuran dan nomor partisi pasca-acak yang optimal, atau melakukan pengoptimalan yang dulu memerlukan petunjuk, misalnya, penanganan gabung miring.
Ini bisa sangat berguna ketika kumpulan statistik tidak diaktifkan atau ketika statistik sudah basi. Hal ini juga berguna di tempat-tempat di mana statistik statis diturunkan tidak akurat, seperti di tengah-tengah query yang rumit, atau setelah terjadinya data miring.
Kemampuan
AQE diaktifkan secara default. Ini memiliki 4 fitur utama:
- Secara dinamis mengubah {i>sort merge joinbroadcast hash join
- Menggabungkan partisi secara dinamis (menggabungkan partisi kecil menjadi partisi berukuran wajar) setelah pertukaran acak. Tugas yang sangat kecil memiliki {i>throughputthroughput
- Secara dinamis menangani kecondongan dalam {i>sort merge joinhashjoin
- Secara dinamis mendeteksi dan menyebarkan hubungan kosong.
- Menggabungkan partisi secara dinamis (menggabungkan partisi kecil menjadi partisi berukuran wajar) setelah pertukaran acak. Tugas yang sangat kecil memiliki {i>throughputthroughput
Aplikasi
AQE berlaku untuk semua kueri yang:
- Non-streaming
- Berisi setidaknya satu pertukaran (biasanya ketika ada gabungan, agregat, atau jendela), satu sub-kueri, atau keduanya.
Tidak semua kueri yang diterapkan AQE perlu dioptimalkan ulang. Pengoptimalan ulang mungkin atau mungkin tidak menghasilkan rencana kueri yang berbeda dari yang dikompilasi secara statis. Untuk menentukan apakah paket kueri telah diubah oleh AQE, lihat bagian berikut, Paket kueri.
Rencana kueri
Bagian ini membahas bagaimana Anda dapat memeriksa rencana kueri dengan cara yang berbeda.
Di bagian ini:
Antarmuka pengguna Spark
AdaptiveSparkPlan
Node
Kueri yang diterapkan AQE berisi satu atau beberapa AdaptiveSparkPlan
simpul, biasanya sebagai simpul akar dari setiap kueri utama atau sub-kueri.
Sebelum kueri berjalan atau saat dijalankan, isFinalPlan
bendera simpul terkait AdaptiveSparkPlan
ditampilkan sebagai false
; setelah eksekusi kueri selesai, isFinalPlan
bendera berubah menjadi true.
Rencana yang berkembang
Diagram rencana kueri berkembang saat eksekusi berlangsung dan mencerminkan rencana terbaru yang sedang dijalankan. {i>Node
Berikut ini adalah contoh diagram rencana kueri:
DataFrame.explain()
AdaptiveSparkPlan
Node
Kueri yang diterapkan AQE berisi satu atau beberapa AdaptiveSparkPlan
simpul, biasanya sebagai simpul akar dari setiap kueri utama atau sub-kueri. Sebelum kueri berjalan atau saat dijalankan, isFinalPlan
bendera simpul terkait AdaptiveSparkPlan
ditampilkan sebagai false
; setelah eksekusi kueri selesai, isFinalPlan
bendera berubah menjadi true
.
Rencana saat ini dan awal
Di bawah setiap AdaptiveSparkPlan
simpul akan ada paket awal (rencana sebelum menerapkan pengoptimalan AQE) dan paket saat ini atau akhir, tergantung pada apakah eksekusi telah selesai. Rencana saat ini akan berkembang saat eksekusi berlangsung.
Statistik {i>runtime
Setiap tahap acak dan siaran berisi statistik data.
Sebelum tahap berjalan atau ketika tahap sedang berjalan, statistik adalah perkiraan waktu kompilasi, dan bendera isRuntime
adalah false
, misalnya: Statistics(sizeInBytes=1024.0 KiB, rowCount=4, isRuntime=false);
Setelah eksekusi tahap selesai, statistiknya adalah yang dikumpulkan saat runtime, dan bendera isRuntime
akan menjadi true
, misalnya: Statistics(sizeInBytes=658.1 KiB, rowCount=2.81E+4, isRuntime=true)
Berikut ini adalah DataFrame.explain
contoh:
Sebelum eksekusi
Selama eksekusi
Sebelum eksekusi
SQL EXPLAIN
AdaptiveSparkPlan
Node
Kueri yang diterapkan AQE berisi satu atau beberapa {i>node node
Tidak ada paket saat ini
Seperti SQL EXPLAIN
tidak mengeksekusi kueri, rencana saat ini selalu sama dengan rencana awal dan tidak mencerminkan apa yang pada akhirnya akan dieksekusi oleh AQE.
Berikut ini adalah contoh penjelasan SQL:
Efektivitas
Rencana kueri akan berubah jika satu atau beberapa pengoptimalan AQE berlaku. Efek dari pengoptimalan AQE ini ditunjukkan oleh perbedaan antara rencana saat ini dan akhir dan rencana awal dan {i>node
Secara dinamis mengubah {i>sort merge joinbroadcast hash joinnode
Partisi coalesce dinamis: node Menangani gabungan condong secara dinamis: simpul Secara dinamis mendeteksi dan menyebarkan hubungan kosong: bagian dari (atau keseluruhan) rencana digantikan oleh {i>node
CustomShuffleReader
dengan properti Coalesced
SortMergeJoin
dengan bidang isSkew
sebagai true.Konfigurasi
Di bagian ini:
Mengaktifkan dan menonaktifkan eksekusi kueri adaptif
Properti
spark.databricks.optimizer.adaptive.enabled
Jenis: Boolean
Apakah akan mengaktifkan dan menonaktifkan eksekusi kueri adaptif.
Nilai default: true
Aktifkan pengacakan yang dioptimalkan secara otomatis
Properti
spark.sql.shuffle.partitions
Jenis: Integer
Jumlah default partisi yang akan digunakan saat mengacak data untuk gabungan atau agregasi. Mengatur nilai auto
memungkinkan pengacakan yang dioptimalkan secara otomatis, yang secara otomatis menentukan angka ini berdasarkan rencana kueri dan ukuran data input kueri.
Catatan: Untuk Streaming Terstruktur, konfigurasi ini tidak dapat diubah antara kueri dimulai ulang dari lokasi titik pemeriksaan yang sama.
Nilai default: 200Secara dinamis mengubah {i>sort merge joinbroadcast hash join
Properti
spark.databricks.adaptive.autoBroadcastJoinThreshold
Jenis: Byte String
Ambang batas untuk memicu pengalihan ke siaran bergabung saat {i>runtime
Nilai default: 30MB
Menggabungkan partisi secara dinamis
Properti
spark.sql.adaptive.coalescePartitions.enabled
Jenis: Boolean
Apakah akan mengaktifkan atau menonaktifkan penggabungan partisi.
Nilai default: true
spark.sql.adaptive.advisoryPartitionSizeInBytes
Jenis: Byte String
Ukuran target setelah penggabungan. Ukuran partisi yang digabungkan akan mendekati tetapi tidak lebih besar dari ukuran target ini.
Nilai default: 64MB
spark.sql.adaptive.coalescePartitions.minPartitionSize
Jenis: Byte String
Ukuran minimum partisi setelah penggabungan. Ukuran partisi yang menyatu tidak akan lebih kecil dari ukuran ini.
Nilai default: 1MB
spark.sql.adaptive.coalescePartitions.minPartitionNum
Jenis: Integer
Ukuran minimum partisi setelah penggabungan. Tidak disarankan, karena pengaturan secara eksplisit mengambil alihspark.sql.adaptive.coalescePartitions.minPartitionSize
.
Nilai default: 2x tidak. dari core clusterMenghandle gabungan miring secara dinamis
Properti
spark.sql.adaptive.skewJoin.enabled
Jenis: Boolean
Apakah akan mengaktifkan atau menonaktifkan penanganan gabung {i>skew
Nilai default: true
spark.sql.adaptive.skewJoin.skewedPartitionFactor
Jenis: Integer
Faktor yang ketika dikalikan dengan ukuran partisi median berkontribusi untuk menentukan apakah partisi miring.
Nilai default: 5
spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes
Jenis: Byte String
Ambang batas yang berkontribusi untuk menentukan apakah partisi miring.
Nilai default: 256MB
Partisi dianggap miring ketika keduanya (partition size > skewedPartitionFactor * median partition size)
dan (partition size > skewedPartitionThresholdInBytes)
adalah true
.
Mendeteksi dan menyebarkan hubungan kosong secara dinamis
Properti |
---|
spark.databricks.adaptive.emptyRelationPropagation.enabled Jenis: Boolean Apakah akan mengaktifkan atau menonaktifkan penyebaran hubungan kosong secara dinamis. Nilai default: true |
Pertanyaan yang sering diajukan (FAQ)
Di bagian ini:
- Mengapa AQE tidak menyiarkan tabel gabungan kecil?
- Haruskah saya masih menggunakan petunjuk strategi gabung siaran dengan AQE diaktifkan?
- Apa perbedaan antara petunjuk gabung miring dan pengoptimalan gabung kemiringan AQE? Mana yang harus saya gunakan?
- Mengapa AQE tidak menyesuaikan pesanan gabungan saya secara otomatis?
- Mengapa AQE tidak mendeteksi kemiringan data saya?
Mengapa AQE tidak menyiarkan tabel gabungan kecil?
Jika ukuran hubungan yang diharapkan akan disiarkan tidak termasuk dalam ambang batas ini tetapi masih belum disiarkan:
- Periksa jenis gabung. Siaran tidak didukung untuk jenis gabungan tertentu, misalnya, hubungan kiri
LEFT OUTER JOIN
tidak dapat disiarkan. - Bisa juga bahwa hubungan berisi banyak partisi kosong, dalam hal ini sebagian besar tugas dapat diselesaikan dengan cepat dengan {i>sort merge joinskew joinspark.sql.adaptive.nonEmptyPartitionRatioForBroadcastJoin.
Haruskah saya masih menggunakan petunjuk strategi gabung siaran dengan AQE diaktifkan?
Ya. Gabungan siaran yang direncanakan secara statis biasanya lebih baik daripada yang direncanakan secara dinamis oleh AQE karena AQE mungkin tidak beralih ke gabungan siaran sampai setelah melakukan pengacakan untuk kedua sisi gabungan (pada saat itu ukuran hubungan sebenarnya diperoleh). Jadi menggunakan petunjuk siaran masih bisa menjadi pilihan yang baik jika Anda mengetahui kueri Anda dengan baik. AQE akan menghormati petunjuk kueri dengan cara yang sama seperti pengoptimalan statis, tetapi masih dapat menerapkan pengoptimalan dinamis yang tidak terpengaruh oleh petunjuk.
Apa perbedaan antara petunjuk gabung miring dan pengoptimalan gabung kemiringan AQE? Mana yang harus saya gunakan?
Sebaiknya andalkan penanganan gabungan miring AQE daripada menggunakan petunjuk gabungan miring, karena gabungan miring AQE benar-benar otomatis dan secara umum berforma lebih baik daripada mitra petunjuk.
Mengapa AQE tidak menyesuaikan pesanan gabungan saya secara otomatis?
Pengurusan ulang gabungan dinamis bukan bagian dari AQE.
Mengapa AQE tidak mendeteksi kemiringan data saya?
Ada dua kondisi ukuran yang harus dipenuhi agar AQE mendeteksi partisi sebagai partisi miring:
- Ukuran partisi lebih besar dari
spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes
(default 256MB) - Ukuran partisi lebih besar dari ukuran median semua partisi kali faktor
spark.sql.adaptive.skewJoin.skewedPartitionFactor
partisi miring (default 5)
Selain itu, dukungan penanganan miring terbatas untuk jenis gabungan tertentu, misalnya, di LEFT OUTER JOIN
, hanya miring di sisi kiri yang dapat dioptimalkan.
Warisan
Istilah "Adaptive Execution" telah ada sejak Spark 1.6, tetapi AQE baru di Spark 3.0 pada dasarnya berbeda. Dalam hal fungsionalitas, Spark 1.6 hanya melakukan bagian "partisi yang bergabung secara dinamis". Dalam hal arsitektur teknis, AQE baru adalah kerangka kerja perencanaan dinamis dan perencanaan kueri berdasarkan statistik {i>runtime