Salah satu rekan kerja saya menyebutkan prosedur tersimpan di database SQL Server 2008 R2 kami sp_something
. Ketika saya melihat ini, saya langsung berpikir: "Itu SALAH!" dan mulai mencari bookmark saya untuk artikel online ini yang menjelaskan mengapa itu salah, jadi saya bisa memberikan penjelasan kepada rekan kerja saya.
Dalam artikel (oleh Brian Moran ) dijelaskan bahwa memberikan prosedur tersimpan awalan sp_ membuat SQL Server melihat pada master database untuk rencana yang dikompilasi. Karena sp_sproc
tidak berada di sana, SQL Server akan mengkompilasi ulang prosedur (dan memerlukan kunci kompilasi eksklusif untuk itu, menyebabkan masalah kinerja).
Contoh berikut diberikan dalam artikel untuk menunjukkan perbedaan antara dua prosedur:
USE tempdb;
GO
CREATE PROCEDURE dbo.Select1 AS SELECT 1;
GO
CREATE PROCEDURE dbo.sp_Select1 AS SELECT 1;
GO
EXEC dbo.sp_Select1;
GO
EXEC dbo.Select1;
GO
Anda menjalankan ini, lalu buka Profiler (tambahkan Prosedur Disimpan -> SP:CacheMiss
acara) dan jalankan prosedur yang tersimpan lagi. Anda seharusnya melihat perbedaan antara dua prosedur tersimpan: prosedur sp_Select1
tersimpan akan menghasilkan satu SP:CacheMiss
peristiwa lebih dari Select1
prosedur tersimpan (artikel referensi SQL Server 7.0 dan SQL Server 2000. )
Ketika saya menjalankan contoh di lingkungan SQL Server 2008 R2 saya, saya mendapatkan jumlah SP:CacheMiss
peristiwa yang sama untuk kedua prosedur (baik di tempdb dan di database pengujian lain).
Jadi saya bertanya-tanya:
- Bisakah saya melakukan sesuatu yang salah dalam eksekusi contoh saya?
Apakahsproc sp_something
adagium 'jangan beri nama pengguna ' masih valid di versi SQL Server yang lebih baru?- Jika demikian, apakah ada contoh yang baik yang menunjukkan validitasnya dalam SQL Server 2008 R2?
Terima kasih banyak atas pemikiran Anda tentang ini!
EDIT
Saya menemukan Membuat Prosedur yang Disimpan (Database Engine) di msdn untuk SQL Server 2008 R2, yang menjawab pertanyaan kedua saya:
Kami menyarankan Anda untuk tidak membuat prosedur tersimpan menggunakan sp_ sebagai awalan. SQL Server menggunakan awalan sp_ untuk menunjuk prosedur yang tersimpan sistem. Nama yang Anda pilih mungkin bertentangan dengan beberapa prosedur sistem di masa depan. [...]
Tidak ada yang disebutkan di sana tentang masalah kinerja yang disebabkan oleh penggunaan sp_
awalan. Saya ingin tahu apakah itu masih terjadi atau apakah mereka memperbaikinya setelah SQL Server 2000.
sp_
versi (perlu memeriksa di master dan database pengguna karena memprioritaskan procs sistem dimaster
-> procs di DB pengguna -> bukan sistem procs inmaster
)sp_
? Ini sama bermanfaatnya dengan awalan tabel dengantbl
. Mengapa membuat master pencarian sistem terlebih dahulu (bahkan jika itu diabaikan atau tidak ada perbedaan kinerja) untuk memungkinkan Anda menggunakan konvensi penamaan yang tidak berarti ini?dbo.sp_Author_Rename
lebih baik daripadadbo.Author_Rename
. Saya tidak dapat memikirkan satu hal pun yang masuk akal.Jawaban:
Ini cukup mudah untuk menguji diri Anda. Mari kita buat dua prosedur yang sangat sederhana:
Sekarang mari kita membangun pembungkus yang mengeksekusi mereka beberapa kali, dengan dan tanpa awalan skema:
Hasil:
Kesimpulan:
Pertanyaan yang lebih penting: mengapa Anda ingin menggunakan awalan sp_? Apa yang rekan kerja Anda berharap untuk mendapatkan dari melakukannya? Ini seharusnya bukan tentang Anda harus membuktikan bahwa ini lebih buruk, itu harus tentang mereka membenarkan menambahkan awalan tiga huruf yang sama untuk setiap prosedur tersimpan tunggal dalam sistem. Saya gagal melihat manfaatnya.
Juga saya melakukan beberapa pengujian yang cukup luas dari pola ini di posting blog berikut:
http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix
sumber
sp_
sehingga mereka dapat dibedakan dari hal-hal lain dan tidak ada konflik nama ... Saya tidak tahu ada masalah kinerja ini dengan itu.Seperti yang ditunjukkan oleh komentar sederhana Martin Smith - ya, jika Anda memiliki prosedur tersimpan dengan
sp_
awalan - pelaksana kueri SQL Server akan selalu memeriksa dalammaster
database terlebih dahulu untuk melihat apakah prosedur yang disimpan (ditandai sebagai prosedur yang disimpan sistem) dengan nama itu ada.Dan jika ada, prosedur yang disimpan sistem dari
master
database selalu menang dan akan dieksekusi bukan milik Anda.Jadi ya - itu masih berdiri: tidak menggunakan yang
sp_
awalan.sumber
CREATE PROC dbo.sp_helptext AS SELECT 1
lalu cobaEXEC dbo.sp_helptext
master
sp.Tes yang lebih baik adalah menulis kueri yang memerlukan optimisasi penuh karena kemungkinan itu merupakan cerminan yang lebih baik dari apa yang sedang Anda lakukan. Saya membungkus kueri berikut dalam SP dan mengulangi pengujian Anda dan mendapatkan hasil yang sama.
Saya mendapatkan jumlah cache miss dan hit yang sama dalam kedua kasus dan dalam kedua kasus paket ditambahkan ke cache. Saya juga menjalankan kedua procs beberapa kali dan tidak ada perbedaan yang konsisten dalam waktu CPU atau waktu yang berlalu yang dilaporkan oleh dm_exec_query_stats.
Kekhawatiran lainnya adalah karena procs "sp_" dapat dieksekusi dari master sehingga Anda bisa mendapatkan salinan proc yang dijalankan menjadi master alih-alih DB yang sedang Anda kerjakan, tetapi tes cepat akan menunjukkan bukan itu masalahnya. Namun, jika proc dikeluarkan dari DB tempat Anda bekerja dan salinannya ada di master maka itu akan dieksekusi yang bisa menjadi masalah jika itu versi lama. Jika ini masalah, saya tidak akan menggunakan "sp_" untuk memberi nama proc.
sumber
Saya percaya masalah ini harus dilakukan ketika Anda tidak menentukan nama objek yang memenuhi syarat. Jadi, "EXEC sp_something" akan memeriksa master terlebih dahulu, tetapi "EXEC dbname.dbo.sp_something" tidak akan pernah pergi ke master terlebih dahulu.
Pelajaran, jika saya ingat, adalah untuk selalu menggunakan nama yang sepenuhnya memenuhi syarat.
sumber
EXEC MyDB.dbo.sp_helptext 'sp_helptext'
masih menggunakan yang darimaster
bahkan jika ada satu di basis data pengguna. AFAIK memeriksa kedua lokasi dan akan menggunakan satu darimaster
jika ada dan ditandai sebagai objek sistem.MyDB.dbo.sp_foo
masih dieksekusi versi master). Saya tidak memiliki 2008/2008 R2 sekarang untuk mengkonfirmasi di mana perilaku ini berubah.