फिर भी sp_ के साथ एक उपयोगकर्ता संग्रहीत प्रक्रिया का नाम शुरू करने के लिए गलत है?


33

मेरे एक सह-कार्यकर्ता ने हमारे SQL Server 2008 R2 डेटाबेस में संग्रहीत कार्यविधि का नाम दिया है sp_something। जब मैंने यह देखा, मैंने तुरंत सोचा: "यह गलत है!" और इस ऑनलाइन लेख के लिए मेरे बुकमार्क खोजना शुरू कर दिया, जो बताता है कि यह गलत क्यों है, इसलिए मैं अपने सहकर्मी को स्पष्टीकरण प्रदान कर सकता हूं।

लेख में ( ब्रायन मोरन द्वारा ) यह समझाया गया है कि संग्रहीत प्रक्रिया को एक sp_ उपसर्ग देने से SQL सर्वर एक संकलित योजना के लिए मास्टर डेटाबेस को देखता है। क्योंकि sp_sprocवहाँ निवास नहीं करता है, SQL सर्वर प्रक्रिया को फिर से शुरू करेगा (और उसके लिए एक विशिष्ट संकलन लॉक की आवश्यकता है, जिससे प्रदर्शन समस्याएं हो सकती हैं)।

दो प्रक्रियाओं के बीच अंतर दिखाने के लिए लेख में निम्नलिखित उदाहरण दिया गया है:

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

आप इसे चलाते हैं, फिर Profiler खोलें (संग्रहीत कार्यविधियाँ -> SP:CacheMissईवेंट जोड़ें) और संग्रहीत प्रक्रियाओं को फिर से चलाएँ। आप दो संग्रहीत प्रक्रियाओं के बीच अंतर देखने वाले हैं: sp_Select1संग्रहीत कार्यविधि संग्रहीत कार्यविधि की SP:CacheMissतुलना में एक और घटना उत्पन्न करेगी Select1(लेख SQL Server 7.0 और SQL Server 2000 का संदर्भ देता है ।)

जब मैं अपने SQL Server 2008 R2 वातावरण में उदाहरण चलाता हूं, तो मुझे SP:CacheMissदोनों प्रक्रियाओं के लिए समान मात्रा में (दोनों tempdb में और एक अन्य परीक्षण डेटाबेस में) मिलता है।

तो मैं सोच रहा हूँ:

  • क्या मेरे उदाहरण के निष्पादन में कुछ गलत हो सकता है?
  • sproc sp_somethingSQL सर्वर के नए संस्करणों में 'क्या एक उपयोगकर्ता का नाम नहीं है ' एडैजियम अभी भी मान्य है?
  • यदि हां, तो क्या एक अच्छा उदाहरण है जो SQL Server 2008 R2 में इसकी वैधता दिखाता है?

इस पर आपके विचारों के लिए बहुत बहुत धन्यवाद!

संपादित करें

मैंने SQL सर्वर 2008 R2 के लिए msdn पर संग्रहीत कार्यविधियाँ (डेटाबेस इंजन) बनाना पाया , जो मेरे दूसरे प्रश्न का उत्तर देता है:

हम अनुशंसा करते हैं कि आप उपसर्ग के रूप में sp_ का उपयोग करके किसी भी संग्रहीत कार्यविधियों का निर्माण न करें। SQL सर्वर सिस्टम संग्रहित प्रक्रियाओं को निर्दिष्ट करने के लिए sp_ उपसर्ग का उपयोग करता है। आपके द्वारा चुना गया नाम कुछ भविष्य की प्रणाली प्रक्रिया के साथ संघर्ष कर सकता है। [...]

हालांकि उपसर्ग का उपयोग करके होने वाली प्रदर्शन समस्याओं के बारे में कुछ भी उल्लेख नहीं किया गया है sp_। मुझे यह जानकर अच्छा लगेगा कि यदि यह अभी भी मामला है या यदि उन्होंने इसे SQL Server 2000 के बाद ठीक किया है।


3
मैंने इसे पहले देखा और एक नगण्य प्रदर्शन अंतर पाया, जो मैंने sp_संस्करणों को हल करने के लिए थोड़ा अधिक ओवरहेड में डाल दिया (मास्टर और उपयोगकर्ता डेटाबेस दोनों में जांच करने की आवश्यकता है क्योंकि यह सिस्टम को प्राथमिकता देता है master-> उपयोगकर्ता DB में procs - गैर सिस्टम) में master)
मार्टिन स्मिथ

4
किसी संगृहीत प्रक्रिया को उपसर्ग करने के लिए आप क्या लाभ देखते हैं sp_? यह एक तालिका के साथ उपसर्ग के रूप में उपयोगी है tbl। आप इस व्यर्थ नामकरण सम्मेलन का उपयोग करने की अनुमति देने के लिए सिस्टम खोज मास्टर को पहले (भले ही वह नगण्य या कोई प्रदर्शन अंतर क्यों न हो) बनायें?
आरोन बर्ट्रेंड

1
@AaronBertrand: ईमानदारी से, मैं कोई लाभ नहीं देख सब पर sp_, केवल नुकसान के साथ sprocs लगाकर में, और मैं उन्हें इस तरह से अपने आप को उपसर्ग कभी नहीं होगा। लेकिन मैं चाहता हूं कि मुझे अपने तमाम तर्कों को सहकर्मियों को समझाने के लिए मिल सके।

1
हाँ, tbl बेकार है, लेकिन मुझे अभी भी इसका उपयोग करना पसंद है। मेरा ओसीडी किकिंग में होना चाहिए। अब मेरे लॉन से बाहर निकलें।
SQLRockstar

1
@ जोसेन, आपके सहकर्मियों को नामकरण योजना को और अधिक जटिल बनाने के लिए तर्क के साथ आना चाहिए । उन्हें समझाएं कि dbo.sp_Author_Renameबेहतर क्यों है dbo.Author_Rename। मैं एक भी चीज़ के बारे में नहीं सोच सकता जो समझ में आता है।
हारून बर्ट्रेंड

जवाबों:


31

यह अपने आप को परीक्षण करने के लिए काफी आसान है। चलो दो बहुत ही सरल प्रक्रियाएँ बनाते हैं:

CREATE PROCEDURE dbo.sp_mystuff
AS
  SELECT 'x';
GO
CREATE PROCEDURE dbo.mystuff
AS
  SELECT 'x';
GO

अब आइए एक रैपर का निर्माण करें जो स्कीमा उपसर्ग के साथ और उसके बिना कई बार निष्पादित होता है:

CREATE PROCEDURE dbo.wrapper_sp1
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @i INT = 1;
    WHILE @i <= 1000
    BEGIN
      EXEC sp_mystuff;
      SET @i += 1;
    END
END
GO
CREATE PROCEDURE dbo.wrapper_1
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @i INT = 1;
    WHILE @i <= 1000
    BEGIN
      EXEC mystuff;
      SET @i += 1;
    END
END
GO
CREATE PROCEDURE dbo.wrapper_sp2
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @i INT = 1;
    WHILE @i <= 1000
    BEGIN
      EXEC dbo.sp_mystuff;
      SET @i += 1;
    END
END
GO
CREATE PROCEDURE dbo.wrapper_2
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @i INT = 1;
    WHILE @i <= 1000
    BEGIN
      EXEC dbo.mystuff;
      SET @i += 1;
    END
END
GO

परिणाम:

यहाँ छवि विवरण दर्ज करें

निष्कर्ष:

  • sp_ उपसर्ग का उपयोग धीमा है
  • स्कीमा उपसर्ग को छोड़ना धीमा है

अधिक महत्वपूर्ण सवाल: क्यों तुम होगा चाहते sp_ उपसर्ग उपयोग कैसे करें? आपके सहकर्मियों को ऐसा करने से क्या लाभ होने की उम्मीद है ? यह आपके बारे में यह साबित करने के लिए नहीं होना चाहिए कि यह बदतर है, यह उनके बारे में होना चाहिए कि सिस्टम में हर एक संग्रहित प्रक्रिया में एक ही तीन-अक्षर उपसर्ग जोड़ना उचित हो। मैं लाभ देखने में असफल रहा।

इसके अलावा मैंने इस पैटर्न का कुछ व्यापक परीक्षण निम्नलिखित ब्लॉग पोस्ट में किया है:

http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix


ध्यान दें, ये परिणाम SQL Server 2012 पर हैं। लेकिन आप अपने वातावरण में समान परीक्षण कर सकते हैं।
हारून बर्ट्रेंड

1
"आपके सह-कार्यों को ऐसा करने से क्या लाभ होने की उम्मीद है" हंगेरियन नोटेशन भी देखें । असल में, यह सबसे अधिक भाग के लिए 90 के दशक की बात है। इसके अलावा, मेरी पिछली नौकरी में मानक हर संग्रहीत प्रक्रिया को उपसर्ग करना था sp_ताकि उन्हें अन्य चीजों से अलग किया जा सके और कोई भी नाम संघर्ष न हो ... मुझे नहीं पता था कि यह प्रदर्शन समस्या इसके साथ मौजूद थी।
अर्लज़

महान उदाहरण, धन्यवाद हारून। मैं अभी भी इसे 2008 R2 पर परीक्षण कर रहा हूं (और शायद यह गलत तरीके से परीक्षण कर रहा है, क्योंकि 'dbo.wrapper_sp1' और 'dbo.wrapper_sp2' अन्य दो की तुलना में काफी तेज लगते हैं)।

12

हम अनुशंसा करते हैं कि आप उपसर्ग के रूप में sp_ का उपयोग करके किसी भी संग्रहीत कार्यविधियों का निर्माण न करें। SQL सर्वर सिस्टम संग्रहित प्रक्रियाओं को निर्दिष्ट करने के लिए sp_ उपसर्ग का उपयोग करता है। आपके द्वारा चुना गया नाम कुछ भविष्य की प्रणाली प्रक्रिया के साथ संघर्ष कर सकता है। [...]

हालांकि sp_ उपसर्ग का उपयोग करके होने वाली प्रदर्शन समस्याओं के बारे में कुछ भी उल्लेख नहीं किया गया है। मुझे यह जानकर अच्छा लगेगा कि यह अभी भी मामला है या यदि उन्होंने इसे SQL Server 2000 के बाद ठीक किया है।

जैसा कि मार्टिन स्मिथ की सरल टिप्पणी से पता चलता है - हाँ, यदि आपके पास एक sp_उपसर्ग के साथ संग्रहीत प्रक्रिया है - SQL सर्वर क्वेरी निष्पादक डेटाबेस में हमेशा यह देखने के masterलिए कि क्या कोई संग्रहीत कार्यविधि (सिस्टम संग्रहीत कार्यविधि के रूप में चिह्नित) उस नाम से मौजूद है।

और अगर यह मौजूद है, तो masterडेटाबेस से सिस्टम संग्रहित प्रक्रिया हमेशा बनी रहती है और इसे आपके बजाय निष्पादित किया जाएगा।

तो हाँ - यह अभी भी खड़ा है: का उपयोग नहीं करतेsp_ उपसर्ग।


5
परीक्षण करने के लिए सरल। CREATE PROC dbo.sp_helptext AS SELECT 1फिर कोशिश करेंEXEC dbo.sp_helptext
मार्टिन स्मिथ

आपके उत्तर के लिए धन्यवाद, की व्यापकता पर बहुत उपयोगी जोड़ master sp के ।

2

एक बेहतर परीक्षा एक ऐसी क्वेरी को लिखना है जिसके लिए पूर्ण अनुकूलन की आवश्यकता होती है क्योंकि संभवत: आप जो भी लिख रहे हैं उसका बेहतर प्रतिबिंब हो। मैंने एक एसपी में निम्नलिखित प्रश्न को लपेटा और आपके परीक्षण को दोहराया और उसी परिणाम को प्राप्त किया।

select * from Person.BusinessEntity b
inner join Person.BusinessEntityAddress ba on b.BusinessEntityID = ba.BusinessEntityID
inner join Person.Address a on ba.AddressID = a.AddressID

मुझे दोनों मामलों में समान संख्या में कैश मिस और हिट इवेंट मिले और दोनों ही मामलों में प्लान को कैश में जोड़ा गया। मैंने कई बार दोनों प्रॉक्स भी चलाए और CPU समय या dm_exec_query_stats द्वारा रिपोर्ट किए गए समय में कोई अंतर नहीं था।

दूसरी चिंता यह है कि चूंकि "sp_" procs को मास्टर से निष्पादित किया जा सकता है, इसलिए आपको उस खरीद की एक प्रति मिल सकती है जिसे आप DB के बजाय मास्टर में चला रहे थे, लेकिन एक त्वरित परीक्षण दिखाएगा कि ऐसा नहीं है। हालाँकि, यदि खरीद उस DB से गिरा दी जाती है जिसमें आप काम कर रहे हैं और एक प्रति मास्टर में मौजूद है तो उसे निष्पादित किया जाएगा जो कि एक पुराना संस्करण है, तो यह एक समस्या हो सकती है। अगर यह एक चिंता है तो मैं "sp_" का उपयोग खरीद के नाम के लिए नहीं करूंगा।


दिलचस्प लगता है, धन्यवाद! मैं कुछ और परीक्षण चलाने के लिए हारून के उदाहरण के साथ आपके उदाहरण का उपयोग करूँगा ।

1

मेरा मानना ​​है कि जब आप पूरी तरह से योग्य वस्तु का नाम निर्दिष्ट नहीं करते हैं तो समस्या का सामना करना पड़ता है। तो, "EXEC sp_something" पहले मास्टर की जांच करेगा, लेकिन "EXEC dbname.dbo.sp_something" पहले कभी मास्टर नहीं जाएगा।

सबक, अगर मुझे याद है, हमेशा पूरी तरह से योग्य नाम का उपयोग करना है।


5
ऐसा मत सोचो कि इससे कोई फर्क पड़ता है। EXEC MyDB.dbo.sp_helptext 'sp_helptext'अभी masterभी उपयोगकर्ता डेटाबेस में एक से एक का उपयोग करता है । AFAIK यह दोनों स्थानों की जाँच करता masterहै और यदि यह मौजूद है और सिस्टम ऑब्जेक्ट के रूप में चिह्नित है, तो इसका उपयोग करेगा ।
मार्टिन स्मिथ

1
2012 में @MartinSmith मैं निष्पादित किए जाने वाले मास्टर संस्करण का ज़बरदस्ती नहीं कर सकता था (हालाँकि मेरे परीक्षणों से पता चलता है कि वहाँ कुछ चल रहा है), जब तक कि मैंने स्थानीय प्रति नहीं गिरा दी (जिस स्थिति में MyDB.dbo.sp_fooअभी भी मास्टर संस्करण निष्पादित किया गया है)। मेरे पास 2008/2008 R2 के पास अभी यह पुष्टि करने के लिए नहीं है कि यह व्यवहार कहाँ बदला गया है।
आरोन बर्ट्रेंड

@AaronBertrand - आह, दिलचस्प मैंने अपना परीक्षण 2008 R2 को किया था।
मार्टिन स्मिथ

यह भी ध्यान दें कि यदि एक स्थानीय प्रक्रिया नहीं मिली है और एक मास्टर में पाया जाता है, तो उत्तरार्द्ध निष्पादित किया जाएगा, और ऐसा होने के लिए सिस्टम ऑब्जेक्ट के रूप में चिह्नित करने की आवश्यकता नहीं है। और 2012 में कम से कम, मास्टर कॉपी को सिस्टम ऑब्जेक्ट के रूप में चिह्नित किया गया है या नहीं, व्यवहार में परिवर्तन नहीं करता है - स्थानीय डीबी / स्कीमा उपसर्ग के साथ या उसके बिना, स्थानीय कॉपी को हमेशा तब तक निष्पादित किया जाता है जब तक कि यह मौजूद नहीं है।
हारून बर्ट्रेंड

1
उफ़, मुझे स्पष्ट करना चाहिए कि मेरी टिप्पणी का सुझाव दिए गए उत्तर पर था। SQLRockstar की टिप्पणी "EXEC dbname.dbo.sp_something पहले कभी नहीं जाएगी।" गलत है।
ग्रीनस्टोन वाकर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.