Arsitektur Integrasi CLR - Performa

Berlaku untuk: SQL Server Azure SQL Managed Instance

Topik ini membahas beberapa pilihan desain yang meningkatkan performa integrasi Microsoft SQL Server dengan Microsoft .NET Framework runtime bahasa umum (CLR).

Proses Kompilasi

Selama kompilasi ekspresi SQL, ketika referensi ke rutinitas terkelola ditemui, stub bahasa perantara Microsoft (MSIL) dihasilkan. Rintik ini mencakup kode untuk marshal parameter rutin dari SQL Server ke CLR, memanggil fungsi, dan mengembalikan hasilnya. Kode "lem" ini didasarkan pada jenis parameter dan pada arah parameter (masuk, keluar, atau referensi).

Kode lem memungkinkan pengoptimalan khusus jenis dan memastikan penerapan semantik SQL Server yang efisien, seperti nullability, membatasi faset, berdasarkan nilai, dan penanganan pengecualian standar. Dengan menghasilkan kode untuk jenis argumen yang tepat, Anda menghindari pemaksaan jenis atau biaya pembuatan objek pembungkus (disebut "tinju") di seluruh batas pemanggilan.

Stub yang dihasilkan kemudian dikompilasi ke kode asli dan dioptimalkan untuk arsitektur perangkat keras tertentu di mana SQL Server dijalankan, menggunakan layanan kompilasi JIT (just-in-time) CLR. Layanan JIT dipanggil pada tingkat metode dan memungkinkan lingkungan hosting SQL Server untuk membuat satu unit kompilasi yang mencakup eksekusi SQL Server dan CLR. Setelah stub dikompilasi, penunjuk fungsi yang dihasilkan menjadi implementasi run-time fungsi. Pendekatan pembuatan kode ini memastikan bahwa tidak ada biaya pemanggilan tambahan yang terkait dengan refleksi atau akses metadata pada durasi.

Transisi Cepat Antara SQL Server dan CLR

Proses kompilasi menghasilkan penunjuk fungsi yang dapat dipanggil pada durasi dari kode asli. Dalam kasus fungsi yang ditentukan pengguna bernilai skalar, pemanggilan fungsi ini terjadi berdasarkan per baris. Untuk meminimalkan biaya transisi antara SQL Server dan CLR, pernyataan yang berisi pemanggilan terkelola memiliki langkah startup untuk mengidentifikasi domain aplikasi target. Langkah identifikasi ini mengurangi biaya transisi untuk setiap baris.

Pertimbangan Performa

Berikut ini merangkum pertimbangan performa khusus untuk integrasi CLR dalam SQL Server. Informasi lebih rinci dapat ditemukan di "Menggunakan Integrasi CLR di SQL Server 2005" di situs Web MSDN. Informasi umum mengenai performa kode terkelola dapat ditemukan di "Meningkatkan Performa dan Skalabilitas Aplikasi .NET" di situs Web MSDN.

Fungsi yang Ditentukan Pengguna

Fungsi CLR mendapat manfaat dari jalur pemanggilan yang lebih cepat daripada fungsi yang ditentukan pengguna Transact-SQL. Selain itu, kode terkelola memiliki keunggulan performa yang menentukan daripada Transact-SQL dalam hal kode prosedural, komputasi, dan manipulasi string. Fungsi CLR yang intensif komputasi dan yang tidak melakukan akses data lebih baik ditulis dalam kode terkelola. Namun, fungsi Transact-SQL melakukan akses data lebih efisien daripada integrasi CLR.

Agregat yang Ditentukan Pengguna

Kode terkelola dapat secara signifikan mengungguli agregasi berbasis kursor. Kode terkelola umumnya berkinerja sedikit lebih lambat daripada fungsi agregat SQL Server bawaan. Kami menyarankan agar jika ada fungsi agregat bawaan asli, Anda harus menggunakannya. Dalam kasus di mana agregasi yang diperlukan tidak didukung secara asli, pertimbangkan agregat yang ditentukan pengguna CLR atas implementasi berbasis kursor karena alasan performa.

Streaming Table-Valued Functions

Aplikasi sering kali perlu mengembalikan tabel sebagai akibat dari memanggil fungsi. Contohnya termasuk membaca data tabular dari file sebagai bagian dari operasi impor, dan mengonversi nilai yang dipisahkan koma menjadi representasi relasional. Biasanya, Anda dapat menyelesaikan ini dengan mewujudkan dan mengisi tabel hasil sebelum dapat dikonsumsi oleh pemanggil. Integrasi CLR ke dalam SQL Server memperkenalkan mekanisme ekstensibilitas baru yang disebut fungsi bernilai tabel streaming (STVF). STVF terkelola berkinerja lebih baik daripada implementasi prosedur tersimpan yang diperpanjang yang sebanding.

STVF adalah fungsi terkelola yang mengembalikan antarmuka IEnumerable . IEnumerable memiliki metode untuk menavigasi tataan hasil yang dikembalikan oleh STVF. Ketika STVF dipanggil, IEnumerable yang dikembalikan terhubung langsung ke rencana kueri. Paket kueri memanggil metode IEnumerable saat perlu mengambil baris. Model iterasi ini memungkinkan hasil dikonsumsi segera setelah baris pertama diproduksi, alih-alih menunggu sampai seluruh tabel diisi. Ini juga secara signifikan mengurangi memori yang dikonsumsi dengan memanggil fungsi .

Array vs. Kursor

Ketika kursor Transact-SQL harus melintasi data yang lebih mudah diekspresikan sebagai array, kode terkelola dapat digunakan dengan perolehan performa yang signifikan.

String Data

SQL Server data karakter, seperti varchar, dapat berupa jenis SqlString atau SqlChars dalam fungsi terkelola. Variabel SqlString membuat instans dari seluruh nilai ke dalam memori. Variabel SqlChars menyediakan antarmuka streaming yang dapat digunakan untuk mencapai performa dan skalabilitas yang lebih baik dengan tidak membuat instans dari seluruh nilai ke dalam memori. Ini menjadi sangat penting untuk data objek besar (LOB). Selain itu, data XML server dapat diakses melalui antarmuka streaming yang dikembalikan oleh SqlXml.CreateReader().

CLR vs. Extended Stored Procedures

Antarmuka pemrograman aplikasi (API) Microsoft.SqlServer.Server yang memungkinkan prosedur terkelola untuk mengirim kumpulan hasil kembali ke klien berperforma lebih baik daripada API Open Data Services (ODS) yang digunakan oleh prosedur tersimpan yang diperluas. Selain itu, API System.Data.SqlServer mendukung jenis data seperti xml, varchar(max), nvarchar(max), dan varbinary(max), yang diperkenalkan dalam SQL Server 2005 (9.x), sementara API ODS belum diperluas untuk mendukung jenis data baru.

Dengan kode terkelola, SQL Server mengelola penggunaan sumber daya seperti memori, utas, dan sinkronisasi. Ini karena API terkelola yang mengekspos sumber daya ini diimplementasikan di atas SQL Server resource manager. Sebaliknya, SQL Server tidak memiliki tampilan atau kontrol atas penggunaan sumber daya prosedur tersimpan yang diperluas. Misalnya, jika prosedur tersimpan yang diperluas menggunakan terlalu banyak sumber daya CPU atau memori, tidak ada cara untuk mendeteksi atau mengontrolnya dengan SQL Server. Namun, dengan kode terkelola, SQL Server dapat mendeteksi bahwa utas tertentu belum menghasilkan untuk jangka waktu yang lama, dan kemudian memaksa tugas untuk menghasilkan sehingga pekerjaan lain dapat dijadwalkan. Akibatnya, menggunakan kode terkelola memberikan skalabilitas dan penggunaan sumber daya sistem yang lebih baik.

Kode terkelola dapat menimbulkan overhead tambahan yang diperlukan untuk mempertahankan lingkungan eksekusi dan melakukan pemeriksaan keamanan. Ini adalah kasus, misalnya, saat berjalan di dalam SQL Server dan banyak transisi dari terkelola ke kode asli diperlukan (karena SQL Server perlu melakukan pemeliharaan tambahan pada pengaturan khusus utas saat pindah ke kode asli dan kembali). Akibatnya, prosedur tersimpan yang diperluas dapat secara signifikan mengungguli kode terkelola yang berjalan di dalam SQL Server untuk kasus di mana sering terjadi transisi antara kode terkelola dan asli.

Catatan

Disarankan agar Anda tidak mengembangkan prosedur tersimpan baru yang diperluas, karena fitur ini telah ditolak.

Serialisasi Asli untuk Jenis User-Defined

Jenis yang ditentukan pengguna (UDT) dirancang sebagai mekanisme ekstensibilitas untuk sistem jenis skalar. SQL Server menerapkan format serialisasi untuk UDT yang disebut Format.Native. Selama kompilasi, struktur jenis diperiksa untuk menghasilkan MSIL yang disesuaikan untuk definisi jenis tertentu.

Serialisasi asli adalah implementasi default untuk SQL Server. Serialisasi yang ditentukan pengguna memanggil metode yang ditentukan oleh penulis jenis untuk melakukan serialisasi. Serialisasi Format.Native harus digunakan jika memungkinkan untuk performa terbaik.

Normalisasi UDT yang Sebanding

Operasi relasional, seperti mengurutkan dan membandingkan UDT, beroperasi langsung pada representasi biner nilai. Hal ini dicapai dengan menyimpan representasi normalisasi (urutan biner) dari status UDT pada disk.

Normalisasi memiliki dua manfaat: itu membuat operasi perbandingan jauh lebih murah dengan menghindari konstruksi instans jenis dan overhead pemanggilan metode; dan membuat domain biner untuk UDT, memungkinkan pembangunan histogram, indeks, dan histogram untuk nilai jenis. Akibatnya, UDT yang dinormalisasi memiliki profil performa yang sangat mirip dengan jenis bawaan asli untuk operasi yang tidak melibatkan pemanggilan metode.

Penggunaan Memori yang Dapat Diskalakan

Agar pengumpulan sampah terkelola dapat berkinerja dan menskalakan dengan baik dalam SQL Server, hindari alokasi tunggal yang besar. Alokasi yang berukuran lebih besar dari 88 kilobyte (KB) akan ditempatkan pada Tumpukan Objek Besar, yang akan menyebabkan pengumpulan sampah berkinerja dan menskalakan jauh lebih buruk daripada banyak alokasi yang lebih kecil. Misalnya, jika Anda perlu mengalokasikan array multi-dimensi besar, lebih baik mengalokasikan array berjarum (tersebar).

Lihat juga

Jenis yang Ditentukan Pengguna CLR