हाँ।
निर्दिष्ट करने में विफल होने का 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 डेटा एक्सेस तक ले जाने की आवश्यकता होगी। फ़ंक्शन के गैर-नियतात्मक होने पर इस आंदोलन को रोका जाता है।
ठीक कर
इस उदाहरण के लिए दो चरणों में शामिल हैं:
- जोड़ना
WITH SCHEMABINDING
- फ़ंक्शन को निर्धारक बनाएं
पहला कदम तुच्छ है। दूसरे में स्ट्रिंग से गैर-नियतात्मक निहित कलाकारों को निकालना शामिल है 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;
यह फ़ंक्शन परिभाषा स्कैन योजना का उत्पादन करती है, और गुण दिखाती है कि यह गैर-नियतात्मक रहता है: