Bagikan melalui


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.

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:

Query plan diagram

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

    Before execution

  • Selama eksekusi

    During execution

  • Sebelum eksekusi

    After execution

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:

SQL explain

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

    Join strategy string

  • Partisi coalesce dinamis: node CustomShuffleReader dengan properti Coalesced

    Custom shuffle reader

    Custom shuffle reader string

  • Menangani gabungan condong secara dinamis: simpul SortMergeJoin dengan bidang isSkew sebagai true.

    Skew join plan

    Skew join string

  • Secara dinamis mendeteksi dan menyebarkan hubungan kosong: bagian dari (atau keseluruhan) rencana digantikan oleh {i>node

    Local table scan

    Local table scan string

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: 200

Secara 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 alih
spark.sql.adaptive.coalescePartitions.minPartitionSize.

Nilai default: 2x tidak. dari core cluster

Menghandle 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?

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