Efisiensi prosedur tersimpan vs kueri mentah

23

Saya telah membaca banyak di kedua sisi perdebatan ini: adakah keuntungan kinerja yang signifikan yang bisa didapat dengan menggunakan hanya prosedur yang tersimpan selama permintaan mentah? Saya secara khusus tertarik pada SQL Server tetapi akan tertarik pada setiap dan semua basis data.

rangsangan
sumber
2
Bisakah Anda memposting tautan ke beberapa yang sudah Anda baca? Saya tidak berpikir kinerja dipertaruhkan di sini (setidaknya tidak secara langsung)
Jack Douglas
1
@ JackDouglas, periksa jawaban mrdenny. Kinerja adalah bagian dari pertanyaan / jawaban ini.
Thomas Stringer

Jawaban:

31

Ini kurang begitu di SQL Server 2008 dan lebih tinggi, tetapi masih ada. Apa yang terjadi adalah cache rencana eksekusi dan SQL Server dapat melakukan auto-parametrize kueri yang dikirim. Ketika menggunakan prosedur tersimpan (yang tidak memiliki SQL dinamis di dalamnya) kueri sudah diparameterisasi sehingga SQL Server tidak melakukannya t perlu membuat paket untuk setiap permintaan saat dijalankan karena paket sudah tersimpan dalam cache paket.

Dan jangan lupa tentang masalah keamanan (SQL dinamis, izin minimum, dll.) Yang hilang saat menggunakan prosedur tersimpan.

Ketika aplikasi menggunakan SQL dinamis terhadap tabel dasar untuk memilih, menyisipkan, memperbarui dan menghapus data dalam tabel, aplikasi harus memiliki hak untuk semua objek secara langsung. Jadi, jika seseorang menggunakan SQL Injection untuk masuk ke server mereka akan memiliki hak untuk meminta, mengubah atau menghapus semua data dalam tabel tersebut.

Jika Anda menggunakan prosedur tersimpan, mereka hanya memiliki hak untuk menjalankan prosedur tersimpan dengan hanya mengembalikan informasi yang akan dikembalikan oleh prosedur tersimpan. Alih-alih mengeluarkan pernyataan penghapusan cepat dan membuang segalanya, mereka perlu mencari tahu prosedur apa yang dapat digunakan untuk menghapus data, lalu mencari cara menggunakan prosedur untuk melakukannya.

Mengingat bahwa SQL Injection adalah cara termudah untuk masuk ke dalam basis data, ini agak penting.

mrdenny
sumber
@ Mrdenny - dapatkah Anda mendapatkan efek yang sama dengan "kueri mentah" jika parameternya?
Jack Douglas
Ya, jika mereka sepenuhnya parametrized. Namun itu tidak mengatasi masalah keamanan yang diselesaikan dengan prosedur tersimpan.
mrdenny
10

Sebagai tambahan untuk jawaban Denny, tidak jarang menemukan sistem di mana memori buffer pool yang signifikan terbuang untuk rencana eksekusi ad-hoc penggunaan tunggal atau rendah, dibuat sebagai hasil dari pertanyaan yang digunakan atas procs.

Kasus terburuk akhir-akhir ini, 8GB dialokasikan untuk instance, cache rencana 3GB, paket penggunaan tunggal 2,5GB. Sebagian besar dari ini adalah SQL2005 sehingga belum menjadi opsi untuk mencoba mengoptimalkan pengaturan beban kerja ad-hoc.

Sudah pasti semakin sulit untuk memasukkan kinerja dalam pembenaran untuk prosedur atas permintaan mentah. Salah satu argumen terkuat bagi saya sekarang adalah "Jika Anda menggunakan prosedur, jauh lebih mudah bagi saya untuk membantu ketika masalah kinerja muncul". Antarmuka dinamis / linq / orm tidak mencegah Anda dari penyetelan, tetapi sangat membatasi opsi Anda.

Mark Storey-Smith
sumber
Ada artikel terkait yang bagus di sini, termasuk skrip untuk menghapus paket sekali pakai itu. sqlskills.com/blogs/kimberly/…
SomeGuy
7

SQL Server menyimpan dan mengoptimalkan prosedur tersimpan dan ad-hoc SQL dengan cara yang sama. Sebagai contoh, prosedur ini:

create procedure dbo.TestSB(@id int) as select * from Orders where id = @id

Akan dioptimalkan dan di-cache secara identik ke:

select * from Orders where id = @id

Namun, ad-hoc SQL berikut ini tidak dapat di-cache secara efektif, karena nilai hardcoded:

select * from Orders where id = 42

Meskipun kinerjanya sama, ada alasan bagus untuk menggunakan prosedur tersimpan. Prosedur tersimpan memberikan pemisahan yang jelas antara DBA dan pengembang aplikasi. Adalah baik untuk memiliki lapisan pertahanan ekstra antara data berharga Anda dan program yang terus berubah :)

Andomar
sumber
+1 terutama jika Anda memaksa semua akses untuk melalui SP Anda dan mereka dipikirkan dengan baik sebagai API transaksional bukan hanya lapisan CRUD
Jack Douglas
Pada 2008+ id = 42kueri dapat dioptimalkan menggunakan paket yang sama tergantung pada pengaturan parameterisasi sederhana / paksa. Tentu saja pertanyaan harus diparameterisasi dengan benar. :-)
Aaron Bertrand