Performa arsitektur integrasi CLR
Berlaku untuk: SQL Server Azure SQL Managed Instance
Artikel ini membahas beberapa pilihan desain yang meningkatkan performa integrasi SQL Server dengan microsoft .NET Framework common language runtime (CLR).
Proses kompilasi
Selama kompilasi ekspresi SQL, ketika referensi ke rutinitas terkelola ditemui, stub bahasa perantara Microsoft (MSIL) dihasilkan. Stub ini mencakup kode untuk melakukan 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 penegakan 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 koersi 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 tempat SQL Server dijalankan, menggunakan layanan kompilasi just-in-time (JIT) 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 waktu proses.
Transisi cepat antara SQL Server dan CLR
Proses kompilasi menghasilkan penunjuk fungsi yang dapat dipanggil pada waktu proses dari kode asli. Untuk 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
Bagian berikut ini meringkas pertimbangan performa khusus untuk integrasi CLR di SQL Server. Untuk informasi selengkapnya, lihat Menggunakan Integrasi CLR di SQL Server 2005. Untuk informasi tentang performa kode terkelola, lihat Meningkatkan Performa dan Skalabilitas Aplikasi .NET.
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. Sebaiknya 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 fungsi bernilai tabel
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 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 IEnumerable
antarmuka. IEnumerable
memiliki metode untuk menavigasi tataan hasil yang dikembalikan oleh STVF. Saat STVF dipanggil, yang dikembalikan IEnumerable
terhubung langsung ke rencana kueri. Paket kueri memanggil IEnumerable
metode saat perlu mengambil baris. Model iterasi ini memungkinkan hasil untuk 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.
Data string
Data karakter SQL Server, seperti varchar, dapat berupa jenis SqlString atau SqlChars dalam fungsi terkelola. Variabel SqlString membuat instans 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 penting untuk data objek besar (LOB). Selain itu, data XML server dapat diakses melalui antarmuka streaming yang dikembalikan oleh SqlXml.CreateReader()
.
CLR vs. prosedur tersimpan yang diperluas
Antarmuka Microsoft.SqlServer.Server
pemrograman aplikasi (API) yang memungkinkan prosedur terkelola untuk mengirim kumpulan hasil kembali ke klien berkinerja 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 di 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 manajer sumber daya SQL Server. 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 mengontrol ini 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. Jadi, menggunakan kode terkelola menyediakan skalabilitas dan penggunaan sumber daya sistem yang lebih baik.
Kode terkelola mungkin menimbulkan overhead ekstra yang diperlukan untuk mempertahankan lingkungan eksekusi dan melakukan pemeriksaan keamanan. Ini adalah kasus, misalnya, ketika berjalan di dalam SQL Server dan banyak transisi dari kode terkelola ke asli diperlukan (karena SQL Server perlu melakukan pemeliharaan ekstra pada pengaturan khusus utas saat pindah ke kode asli dan kembali). Jadi, 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
Jangan kembangkan prosedur tersimpan baru yang diperluas, karena fitur ini tidak digunakan lagi.
Serialisasi asli untuk jenis yang ditentukan pengguna
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. Format.Native
serialisasi harus digunakan jika memungkinkan untuk performa terbaik.
Normalisasi UDT yang sebanding
Operasi relasional, seperti pengurutan dan perbandingan UDT, beroperasi langsung pada representasi biner nilai. Hal ini dilakukan dengan menyimpan representasi yang dinormalisasi (diurutkan biner) dari status UDT pada disk.
Normalisasi memiliki dua manfaat:
itu membuat operasi perbandingan jauh lebih murah dengan menghindari pembangunan instans jenis dan overhead pemanggilan metode
ini membuat domain biner untuk UDT, memungkinkan pembangunan histogram, indeks, dan histogram untuk nilai jenis.
Jadi, UDT yang dinormalisasi memiliki profil performa yang sama 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 di SQL Server, hindari alokasi tunggal yang besar. Alokasi berukuran lebih besar dari 88 kilobyte (KB) ditempatkan pada Tumpukan Objek Besar, yang menyebabkan pengumpulan sampah berkinerja dan menskalakan lebih buruk daripada banyak alokasi yang lebih kecil. Misalnya, jika Anda perlu mengalokasikan array multi-dimensi besar, lebih baik mengalokasikan array jagged (tersebar).