چرا و چهوقت از پیشوند sp_ برای رویههای ذخیرهشده SQL Server استفاده کنیم (و نکنیم)
بسیاری از توسعهدهندگان و مدیران پایگاه داده هنگام ایجاد رویههای ذخیرهشده جدید در SQL Server، عادت دارند از پیشوند `sp_` استفاده کنند، شبیه به آنچه مایکروسافت برای رویههای سیستمی خود به کار میبرد. با این حال، استفاده از `sp_` برای رویههای ذخیرهشده کاستوم (ایجاد شده توسط کاربر) میتواند تأثیرات منفی قابل توجهی بر عملکرد، وضوح و سازگاری آینده داشته باشد. در این مقاله به بررسی دقیق دلایل این موضوع میپردازیم که چرا باید در مورد استفاده از این پیشوند احتیاط کرد و چه زمانی ممکن است استفاده از آن مناسب باشد.
**چرا مایکروسافت از `sp_` استفاده میکند؟**
مایکروسافت پیشوند `sp_` را برای رویههای سیستمی داخلی خود رزرو کرده است. این رویهها معمولاً در پایگاه داده `master` ذخیره میشوند و برای مدیریت و نگهداری SQL Server ضروری هستند. زمانی که یک رویه با پیشوند `sp_` فراخوانی میشود، SQL Server یک رفتار جستجوی خاص را در پیش میگیرد. این رفتار باعث میشود که SQL Server ابتدا رویه را در پایگاه داده `master` جستجو کند، حتی اگر فراخوانی از پایگاه داده دیگری باشد. این مکانیزم برای رویههای سیستمی مفید است زیرا تضمین میکند که آنها همیشه قابل دسترسی هستند و نیازی به تعیین طرح (schema) یا نام پایگاه داده ندارند.
**چه زمانی باید از `sp_` استفاده کنیم؟**
به طور کلی، موارد استفاده از پیشوند `sp_` برای رویههای ذخیرهشده کاستوم شما بسیار محدود است. تنها زمانی باید این کار را انجام دهید که رویهای را ایجاد میکنید که قرار است در تمام پایگاههای داده در یک سرور قابل دسترسی باشد، بدون اینکه نیاز به ایجاد آن رویه در هر پایگاه داده به صورت جداگانه باشد. این سناریو معمولاً برای:
* ابزارهای داخلی که نیاز به دسترسی سطح سرور دارند.
* رویههای مورد استفاده در سناریوهای replication یا توزیع شده.
* ابزارهای مدیریتی بسیار خاص که باید از `master` یا یک پایگاه داده سیستمی دیگر اجرا شوند.
در اکثر موارد، نیازی به این سطح از دسترسی نیست و استفاده از `sp_` در واقع به ضرر شما خواهد بود.
**چه زمانی نباید از `sp_` استفاده کنیم؟**
در سه دلیل اصلی وجود دارد که چرا باید از استفاده از پیشوند `sp_` برای رویههای ذخیرهشده کاستوم خودداری کنید:
1. **مشکلات عملکردی:**
هنگامی که SQL Server یک رویه ذخیرهشده را با پیشوند `sp_` اجرا میکند، مسیر جستجوی آن با رویههای معمولی متفاوت است. SQL Server ابتدا تلاش میکند تا رویه را در پایگاه داده `master` پیدا کند و سپس در پایگاه داده فعلی. این جستجوی اضافی میتواند سربار عملکردی (performance overhead) ایجاد کند.
(i.e. if the procedure is called sp_MyProcedure SQL Server looks in master first, then msdb, then model, then tempdb, then for a database with the same name as the login then for a database with the same name as the login’s default database, then in the current database)
این به این معنی است که SQL Server قبل از اینکه به پایگاه داده فعلی نگاه کند، چندین پایگاه داده سیستمی را برای یافتن رویه جستجو میکند. اگر رویه در `master` یافت نشود، سپس به جستجو در پایگاه داده فعلی ادامه میدهد. این مسیر جستجوی طولانیتر به زمان بیشتری برای حل نام رویه نیاز دارد. این رفتار را میتوان با مشاهده نحوه کار رویه `sp_helptext` مشاهده کرد:
EXEC sp_helptext N'sys.objects';
همچنین، اگر شما رویهای با پیشوند `sp_` و بدون طرح (schema) ایجاد کنید (مثلاً `CREATE PROCEDURE sp_MyProc AS SELECT 1;`) و سپس آن را بدون تعیین طرح فراخوانی کنید (`EXEC sp_MyProc;`)، SQL Server این مسیر جستجو را طی میکند. برای جلوگیری از این مسیر جستجوی ناکارآمد، همیشه باید هنگام فراخوانی رویههای ذخیرهشده کاستوم، نام طرح (schema) را نیز مشخص کنید، حتی اگر از `sp_` استفاده کرده باشید:
-- این مورد باعث جستجوی غیرضروری در پایگاه داده master میشود
EXEC sp_mysproc;
-- این مورد جستجو در master را دور میزند
EXEC dbo.sp_mysproc;
-- این مورد هم جستجو در master را دور میزند و توصیه میشود
EXEC mysproc;
(and as we know from the previous tip SQL Server tries to find the object in the current database and then within the schemas of that database)
با تعیین طرح، SQL Server مستقیماً به دنبال رویه در پایگاه داده فعلی و طرح مشخص شده میگردد، که بسیار کارآمدتر است.
2. **مشکلات وضوح (Clarity Issues):**
استفاده از `sp_` برای رویههای کاستوم میتواند باعث سردرگمی شود. وقتی یک توسعهدهنده یا مدیر پایگاه داده رویههایی با پیشوند `sp_` را میبیند، ممکن است به اشتباه فکر کند که اینها رویههای سیستمی هستند و رفتار متفاوتی با آنها داشته باشد. این عدم وضوح میتواند منجر به سوءتفاهم در کدبیس و مشکلات در نگهداری شود. تیمها باید بتوانند به سرعت رویههای سیستمی را از رویههای کاستوم تشخیص دهند.
3. **مشکلات آتی (Future Issues):**
مایکروسافت به طور مداوم رویههای سیستمی جدیدی را به SQL Server اضافه میکند. اگر شما یک رویه کاستوم با پیشوند `sp_` ایجاد کنید، همیشه این خطر وجود دارد که در آینده مایکروسافت یک رویه سیستمی با همان نام ایجاد کند. این امر میتواند منجر به تداخل نام (naming conflict) و خطاهای غیرمنتظره در برنامه شما شود. این نوع تداخلها میتوانند یافتن و رفع آنها دشوار باشند.
**به جای `sp_` از چه پیشوندهایی استفاده کنیم؟**
برای جلوگیری از مشکلات فوق، بهترین رویکرد این است که از پیشوندهای مناسب و منحصر به فرد برای رویههای ذخیرهشده کاستوم خود استفاده کنید. پیشنهادهای رایج عبارتند از:
* `usp_` (User Stored Procedure)
* `prc_` (Procedure)
* `proc_` (Procedure)
* یا حتی `p_` (Procedure)
مهمترین نکته این است که یک استاندارد نامگذاری ثابت در تیم یا سازمان خود داشته باشید و به آن پایبند باشید. به عنوان مثال، میتوانید تصمیم بگیرید که تمام رویههای ذخیرهشده شما با `usp_` آغاز شوند:
CREATE PROCEDURE usp_GetCustomerOrders
AS
BEGIN
-- منطق رویه
SELECT * FROM dbo.Orders;
END;
به خاطر داشته باشید که هنگام ایجاد یک رویه، SQL Server به طور پیش فرض مالکیت آن را به `dbo` اختصاص میدهد مگر اینکه صراحتاً مالکی را تعیین کنید. بنابراین، فراخوانی رویهها با `dbo.usp_GetCustomerOrders` همیشه بهترین روش برای عملکرد بهینه و جلوگیری از ابهام است.
در نهایت، استفاده از یک استاندارد نامگذاری مشخص نه تنها به بهبود عملکرد کمک میکند، بلکه وضوح کد را افزایش داده و از مشکلات احتمالی در آینده جلوگیری میکند.