Apakah dukungan untuk Paralel Scalar UDF merupakan permintaan fitur yang masuk akal?

10

Telah didokumentasikan dengan cukup baik bahwa skalar UDF memaksa keseluruhan rencana seri.

Menjalankan fungsi secara paralel

Mengingat sejumlah besar baris masuk ke suatu titik dalam pipa di mana UDF harus dihitung, mengapa mesin tidak bisa hanya mendistribusikannya di antara prosesor? Jika tidak ada keadaan dalam UDF maka perintah itu seharusnya tidak masalah.

Ada klaim tentang UDF sebagai kotak hitam yang harus menggunakan kursor. Saya bisa melihat bahwa kursor pengguna tidak dapat diparalelkan dalam SP untuk kasus-kasus di mana beberapa negara dipertahankan di antara iterasi tetapi sepertinya harus diparalelkan sebaliknya.

Poin ekstra untuk menjelaskan mengapa mesin memaksa keseluruhan rencana menjadi serial, bukan hanya tahap perhitungan UDF.

Apakah dukungan untuk UDF paralel merupakan fitur yang wajar untuk diminta?

crokusek
sumber
1
Reaksi yang tepat tampaknya dicatat dalam jawaban yang diterima untuk tautan Anda, untuk menulis ulang setiap Fungsi yang Ditentukan Pengguna Skalar sebagai kolom tunggal Fungsi Inline Table-Valued . Ini diperluas dengan cara yang sama seperti tampilan, dan dengan demikian sepenuhnya dioptimalkan. Dalam hal ini, apakah pertanyaan Anda masih pantas?
Pieter Geerkens
1
Ya tentang kesuksesan dengan solusi TVF. Saya bertanya karena tampaknya salah untuk menghindari penggunaan konstruksi alami. Tampaknya tidak praktis untuk mengharapkan pengembang SQL baru untuk mempelajari internal UDF.
crokusek
Mengklarifikasi komentar. Sukses dengan ITVF tetapi tidak TVF multi-pernyataan.
crokusek

Jawaban:

17

Telah didokumentasikan dengan cukup baik bahwa UDF memaksakan rencana serial secara keseluruhan.

Saya tidak yakin semuanya terdokumentasi dengan baik.

  • Fungsi T-SQL skalar mencegah paralelisme di mana saja dalam rencana.
  • Fungsi CLR skalar dapat dieksekusi secara paralel, asalkan tidak mengakses database.
  • Fungsi T-SQL bernilai multi-pernyataan tabel memaksa zona serial dalam rencana yang mungkin menggunakan paralelisme di tempat lain.
  • Fungsi T-SQL bernilai tabel inline diperluas seperti tampilan, jadi tidak memiliki efek langsung.

Lihat Memaksa Rencana Eksekusi Paralel dan / atau presentasi Eksekusi Paralel Craig Freedman .

Ada klaim tentang UDF sebagai kotak hitam harus menggunakan kursor.

Klaim ini tidak benar.

Poin ekstra untuk menjelaskan mengapa mesin memaksa keseluruhan rencana menjadi serial, bukan hanya tahap perhitungan UDF.

Pemahaman saya adalah bahwa pembatasan saat ini adalah murni hasil dari detail implementasi tertentu. Tidak ada alasan mendasar mengapa fungsi tidak dapat dieksekusi menggunakan paralelisme.

Secara khusus, fungsi skalar T-SQL dijalankan di dalam konteks T-SQL yang terpisah, yang memperumit operasi, koordinasi, dan shutdown yang benar (terutama dalam kasus kesalahan) secara signifikan.

Sama halnya, variabel tabel mendukung pembacaan paralel (tetapi tidak menulis) secara umum, tetapi variabel tabel yang diekspos oleh fungsi bernilai tabel tidak dapat mendukung pembacaan paralel karena alasan implementasi spesifik. Anda akan membutuhkan seseorang dengan akses kode sumber (dan kebebasan untuk berbagi detail) untuk memberikan jawaban yang berwibawa, saya khawatir.

Apakah dukungan untuk UDF paralel merupakan fitur yang wajar untuk diminta?

Tentu saja, jika Anda dapat membuat kasus yang cukup kuat. Perasaan saya sendiri adalah bahwa pekerjaan yang terlibat akan luas, sehingga proposal Anda harus memenuhi standar yang sangat tinggi. Misalnya, permintaan terkait (dan lebih sederhana) untuk menyediakan fungsi skalar sebaris memiliki dukungan besar, tetapi telah mendekam tidak diterapkan selama bertahun-tahun sekarang.


Anda mungkin ingin membaca makalah Microsoft:

... yang menguraikan pendekatan yang akan diambil Microsoft untuk mengatasi masalah kinerja fungsi skalar T-SQL dalam rilis setelah SQL Server 2017.

Tujuan dari Froid adalah untuk memungkinkan pengembang untuk menggunakan abstraksi UDF dan prosedur tanpa mengurangi kinerja. Froid mencapai tujuan ini menggunakan teknik baru untuk secara otomatis mengkonversi program imperatif menjadi bentuk aljabar relasional yang setara bila memungkinkan. Froid memodelkan blok kode imperatif sebagai ekspresi relasional, dan secara sistematis menggabungkannya menjadi satu ekspresi menggunakan operator Terapkan, sehingga memungkinkan pengoptimal kueri untuk memilih rencana kueri paralel yang efisien dan berorientasi pada set .

(penekanan milikku)


Fungsi T-SQL skalar sebaris sekarang diimplementasikan dalam SQL Server 2019 .

Paul White 9
sumber
11

Seperti yang telah disebutkan Paul dengan tepat dalam jawabannya, tidak ada alasan mendasar mengapa skalar UDF tidak dapat dieksekusi menggunakan paralelisme. Namun, terlepas dari tantangan implementasi, ada alasan lain untuk memaksa mereka menjadi serial. The Froid kertas dikutip oleh Paulus memberikan informasi lebih lanjut tentang ini.

Mengutip dari kertas (Bagian 2.3):

Saat ini, SQL Server tidak menggunakan paralelisme intra-kueri dalam kueri yang memanggil UDF. Metode dapat dirancang untuk mengurangi batasan ini, tetapi mereka memperkenalkan tantangan tambahan, seperti memilih tingkat paralelisme yang tepat untuk setiap doa UDF.

Misalnya, pertimbangkan UDF yang menjalankan kueri SQL lain, seperti yang ada di Gambar 1. Setiap kueri seperti itu sendiri dapat menggunakan paralelisme, dan oleh karena itu, pengoptimal tidak memiliki cara untuk mengetahui cara berbagi thread di seluruh mereka, kecuali jika melihat ke dalam UDF dan memutuskan tingkat paralelisme untuk setiap kueri di dalam (yang berpotensi berubah dari satu permintaan ke permintaan lainnya). Dengan UDF bersarang dan rekursif, masalah ini menjadi lebih sulit untuk dikelola.

Pendekatan Froid, seperti yang dijelaskan dalam makalah, tidak hanya akan menghasilkan rencana paralel, tetapi juga menambahkan banyak manfaat lebih untuk pertanyaan dengan UDF. Intinya, ini merangkum permintaan Anda untuk eksekusi UDF paralel.

Pembaruan: Froid sekarang tersedia sebagai fitur pratinjau SQL Server 2019. Fitur ini disebut "Scalar UDF Inlining". Lebih detail di sini: https://blogs.msdn.microsoft.com/sqlserverstorageengine/2018/11/07/introducing-scalar-udf-inlining/

[Pengungkapan: Saya adalah rekan penulis makalah Froid]

Karthik
sumber
Baik sekali! Jika saya mengerti benar itu akan secara otomatis mengkonversi UDF menjadi ITVF secara internal. Kami telah melakukan ini selama beberapa (w / menyatakan / jika / lain) dan membuat kekacauan yang bagus. Kami bahkan memiliki "kolom" debug.
crokusek
1
Ini sebenarnya tidak mengubah UDF menjadi ITVF, tetapi intuisi Anda benar. Melakukan ini secara manual di tingkat permintaan SQL benar-benar berantakan untuk UDF kompleks. Froid melakukan transformasi ini pada pohon aljabar relasional, yang menghindari kekacauan :)
Karthik
@Karthik dapatkah Anda melihat di dba.stackexchange.com/questions/202211/… . Saya benar-benar ingin tahu bagaimana kinerja Froid dalam kasus yang dijelaskan
Roman Pekar
@Roman Saya sudah mengomentari pertanyaan Anda.
Karthik
1
Terima kasih, @Karthik, untuk pekerjaan yang Anda lakukan di kertas Froid, dan dalam upaya Anda (dan kelompok ') dalam meningkatkan kegunaan skalar UDF :-)
Solomon Rutzky