हैलोवीन प्रोटेक्शन से परे किसी फ़ंक्शन को स्कैमबाइंड करने का कोई लाभ है?


52

यह सर्वविदित है कि SCHEMABINDINGएक अद्यतन योजना में एक अनावश्यक स्पूल से बचा जा सकता है :

यदि आप सरल T-SQL UDFs का उपयोग कर रहे हैं जो किसी भी तालिकाओं को नहीं छूते हैं (अर्थात डेटा का उपयोग नहीं करते हैं), तो सुनिश्चित करें कि आप SCHEMABINDINGUDFs के निर्माण के दौरान विकल्प निर्दिष्ट करें । यह UDFs को स्कीमा-बाउंड करेगा और यह सुनिश्चित करेगा कि क्वेरी ऑप्टिमाइज़र इन UDF को शामिल करने वाली क्वेरी योजनाओं के लिए कोई अनावश्यक स्पूल ऑपरेटर उत्पन्न नहीं करता है।

क्या किसी SCHEMABINDINGफ़ंक्शन के अन्य फायदे हैं , भले ही वह डेटा तक नहीं पहुंचता हो?

जवाबों:


78

हाँ।

निर्दिष्ट करने में विफल होने का WITH SCHEMABINDINGमतलब है कि SQL सर्वर विस्तृत चेक को सामान्य रूप से फ़ंक्शन बॉडी पर छोड़ देता है। यह फ़ंक्शन को डेटा तक पहुंचने के रूप में चिह्नित करता है (जैसा कि प्रश्न में दिए गए लिंक में उल्लेख किया गया है)।

यह एक प्रदर्शन अनुकूलन है। यदि उसने यह धारणा नहीं बनाई है, तो SQL सर्वर को हर फ़ंक्शन इनवोकेशन पर विस्तृत जांच करनी होगी (क्योंकि अनबाउंड फ़ंक्शन किसी भी समय बदल सकता है)।

कर रहे हैं पाँच महत्वपूर्ण कार्य गुण:

  • यह सिद्धांत कि मनुष्य के कार्य स्वतंत्र नहीं होते
  • शुद्धता
  • डेटा प्राप्त करना
  • सिस्टम डेटा एक्सेस
  • सिस्टम सत्यापन

उदाहरण के लिए, निम्नलिखित अनबाउंड स्केलर फ़ंक्शन को लें:

CREATE FUNCTION dbo.F
(
    @i integer
)
RETURNS datetime
AS
BEGIN
    RETURN '19000101';
END;

हम मेटाडेटा फ़ंक्शन का उपयोग करते हुए पांच गुणों को देख सकते हैं:

SELECT 
    IsDeterministic = OBJECTPROPERTYEX(Func.ID, 'IsDeterministic'),
    IsPrecise = OBJECTPROPERTYEX(Func.ID, 'IsPrecise'),
    IsSystemVerified = OBJECTPROPERTYEX(Func.ID, 'IsSystemVerified'),
    UserDataAccess = OBJECTPROPERTYEX(Func.ID, 'UserDataAccess'),
    SystemDataAccess = OBJECTPROPERTYEX(Func.ID, 'SystemDataAccess')
FROM (VALUES(OBJECT_ID(N'dbo.F', N'FN'))) AS Func (ID);

नतीजा

दो डेटा एक्सेस गुण सही सेट किए गए हैं, और अन्य तीन झूठे हैं

यह उन लोगों से परे निहित है जिनकी उम्मीद की जा सकती है (उदाहरण के लिए अनुक्रमित दृश्यों या अनुक्रमित गणना किए गए स्तंभों में उपयोग)।

क्वेरी ऑप्टिमाइज़र पर प्रभाव

नियतत्ववाद विशेष रूप से संपत्ति क्वेरी अनुकूलक प्रभावित करता है। इसमें पुनर्लेखन के प्रकारों के बारे में विस्तृत नियम हैं और इसमें हेरफेर करने की अनुमति दी गई है, और ये गैर-निर्धारक तत्वों के लिए बहुत सीमित हैं। दुष्प्रभाव काफी सूक्ष्म हो सकते हैं।

उदाहरण के लिए, निम्नलिखित दो तालिकाओं पर विचार करें:

CREATE TABLE dbo.T1
(
    SomeInteger integer PRIMARY KEY
);
GO
CREATE TABLE dbo.T2
(
    SomeDate datetime PRIMARY KEY
);

... और एक क्वेरी जो फ़ंक्शन का उपयोग करती है (जैसा कि पहले परिभाषित किया गया है):

SELECT * 
FROM dbo.T1 AS T1
JOIN dbo.T2 AS T2
    ON T2.SomeDate = dbo.F(T1.SomeInteger);

तालिका T2 की तलाश में क्वेरी प्लान अपेक्षा के अनुरूप है:

योजना की तलाश करें

हालाँकि, यदि एक ही तार्किक क्वेरी एक व्युत्पन्न तालिका या सामान्य तालिका अभिव्यक्ति का उपयोग करके लिखी गई है:

WITH CTE AS
(
    SELECT *, dt = dbo.F(T1.SomeInteger) 
    FROM dbo.T1 AS T1
)
SELECT * 
FROM CTE
JOIN dbo.T2 AS T2
    ON T2.SomeDate = CTE.dt;

-- Derived table
SELECT
    *
FROM 
(
    SELECT *, dt = dbo.F(T1.SomeInteger)
    FROM dbo.T1 AS T1
) AS T1
JOIN dbo.T2 AS T2
    ON T2.SomeDate = T1.dt;

निष्पादन योजना में अब एक स्कैन की सुविधा है, जिसमें एक फिल्टर में फंसे हुए कार्य को शामिल करने की योजना है:

स्कैन योजना

यह तब भी होता है जब व्युत्पन्न तालिका या सामान्य तालिका अभिव्यक्ति को एक दृश्य या इन-लाइन फ़ंक्शन द्वारा बदल दिया जाता है। एक FORCESEEKसंकेत (और इसी तरह के अन्य प्रयास) सफल नहीं होंगे:

त्रुटि संदेश

मूल मुद्दा यह है कि क्वेरी ऑप्टिमाइज़र स्वतंत्र रूप से nondeterministic क्वेरी तत्वों को पुन: व्यवस्थित नहीं कर सकता है

एक खोज का उत्पादन करने के लिए, फ़िल्टर विधेयकों को योजना को T2 डेटा एक्सेस तक ले जाने की आवश्यकता होगी। फ़ंक्शन के गैर-नियतात्मक होने पर इस आंदोलन को रोका जाता है।

ठीक कर

इस उदाहरण के लिए दो चरणों में शामिल हैं:

  1. जोड़ना WITH SCHEMABINDING
  2. फ़ंक्शन को निर्धारक बनाएं

पहला कदम तुच्छ है। दूसरे में स्ट्रिंग से गैर-नियतात्मक निहित कलाकारों को निकालना शामिल है datetime; इसे एक नियतात्मक के साथ प्रतिस्थापित करना CONVERTन ही अपने आप में पर्याप्त है

ALTER FUNCTION dbo.F
(
    @i integer
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
    -- Convert with a deterministic style
    RETURN CONVERT(datetime, '19000101', 112);
END;

फ़ंक्शन गुण अब हैं:

नए गुण

आशावादी को मुक्त करने के साथ, सभी उदाहरण अब वांछित तलाश योजना का उत्पादन करते हैं ।


ध्यान दें कि फ़ंक्शन में ए CASTका उपयोग करने datetimeसे काम नहीं चलेगा, क्योंकि उस सिंटैक्स में रूपांतरण शैली निर्दिष्ट करना संभव नहीं है:

ALTER FUNCTION dbo.F
(
    @i integer
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
    -- Convert with a deterministic style
    RETURN CAST('19000101' AS datetime);
END;

यह फ़ंक्शन परिभाषा स्कैन योजना का उत्पादन करती है, और गुण दिखाती है कि यह गैर-नियतात्मक रहता है:

CAST फ़ंक्शन गुण

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.