क्या गणना के स्तंभों में स्केलर यूडीएफ को समानता को रोकने से रोकने का एक तरीका है?


29

SQL सर्वर में स्केलर यूडीएफ के खतरों के बारे में बहुत कुछ लिखा गया है । एक आकस्मिक खोज परिणामों के oodles वापस आ जाएगी।

हालांकि, कुछ स्थान ऐसे हैं जहां एक स्केलर यूडीएफ एकमात्र विकल्प है, हालांकि।

एक उदाहरण के रूप में: एक्सएमएल के साथ काम करते समय: XQuery को एक गणना किए गए कॉलम की परिभाषा के रूप में इस्तेमाल नहीं किया जा सकता है। Microsoft द्वारा प्रलेखित एक विकल्प एक स्केलर UDF का उपयोग करने के लिए एक Scalar UDF में आपके XQuery को इनकैप्सुलेट करने के लिए उपयोग करना है, और फिर एक संगणित कॉलम में इसका उपयोग करना है।

इसके विभिन्न प्रभाव हैं, और कुछ वर्कअराउंड हैं।

  • तालिका द्वारा क्वेरी किए जाने पर पंक्ति द्वारा पंक्ति निष्पादित करें
  • क्रमिक रूप से चलाने के लिए तालिका के खिलाफ सभी प्रश्नों को मजबूर करता है

आप फ़ंक्शन को स्कीमाबाइंड करके पंक्ति-दर-पंक्ति निष्पादन के आसपास प्राप्त कर सकते हैं, और या तो गणना किए गए कॉलम को जारी रख सकते हैं, या इसे अनुक्रमित कर सकते हैं। उन तरीकों में से कोई भी तालिका से टकराने वाले प्रश्नों के मजबूर क्रमांकन को नहीं रोक सकता, तब भी जब स्केलर यूडीएफ को संदर्भित नहीं किया जाता है।

क्या ऐसा करने का कोई ज्ञात तरीका है?

जवाबों:


31

हाँ यदि आप:

  • SQL सर्वर 2014 या बाद में चल रहे हैं; तथा
  • ट्रेस ध्वज 176 सक्रिय के साथ क्वेरी को चलाने में सक्षम हैं ; तथा
  • कंप्यूटेड कॉलम है PERSISTED

विशेष रूप से, कम से कम निम्नलिखित संस्करणों की आवश्यकता है :

  • SQL Server 2016 SP1 के लिए संचयी अद्यतन 2
  • SQL Server 2016 RTM के लिए संचयी अद्यतन 4
  • SQL Server 2014 SP2 के लिए संचयी अद्यतन 6

लेकिन इन सुधारों में शुरू किए गए बग के लिए बग ( 2014 और 2017 के लिए रेफरी) से बचें

ट्रेस ध्वज एक स्टार्ट-अप –Tविकल्प के रूप में प्रभावी है , दोनों वैश्विक और सत्र गुंजाइश का उपयोग कर DBCC TRACEON, और प्रति के साथ OPTION (QUERYTRACEON)या एक योजना गाइड।

ट्रेस फ्लैग 176 लगातार कम्प्यूटेड कॉलम के विस्तार को रोकता है।

किसी कॉलम को संकलित करते समय प्रारंभिक मेटाडेटा लोड प्रदर्शन किया जाता है, न कि केवल सीधे संदर्भित किए गए। इससे मिलान के लिए सभी गणना किए गए स्तंभ परिभाषाएं उपलब्ध हैं, जो आम तौर पर एक अच्छी बात है।

एक दुर्भाग्यपूर्ण पक्ष-प्रभाव के रूप में, यदि लोड किए गए (गणना किए गए) स्तंभों में से एक स्केलर उपयोगकर्ता-परिभाषित फ़ंक्शन का उपयोग करता है, तो इसकी उपस्थिति पूरे क्वेरी के लिए समानता को अक्षम करती है , भले ही गणना किए गए स्तंभ का वास्तव में उपयोग न किया गया हो

ट्रेस फ्लैग 176 इसकी मदद करता है, यदि स्तंभ को जारी रखा जाता है, तो परिभाषा को लोड नहीं करने से (विस्तार के बाद से छोड़ दिया जाता है)। इस तरह, एक स्केलर उपयोगकर्ता-परिभाषित फ़ंक्शन कंपाइलिंग क्वेरी ट्री में कभी मौजूद नहीं होता है, इसलिए समानता अक्षम नहीं होती है।

ट्रेस फ्लैग 176 का मुख्य दोष (केवल हल्के से प्रलेखित होने से अलग) यह है कि यह क्वेरी एक्सप्रेशन को लगातार कंपैस्ड किए गए कॉलम से मेल खाने से रोकता है: यदि क्वेरी में एक्सटेंडेड कंप्यूटेड कॉलम से मेल खाता एक्सप्रेशन है, तो ट्रेस फ्लैग 176 को एक्सप्रेशन से बदल दिया जाएगा। गणना किए गए कॉलम का संदर्भ।

अधिक जानकारी के लिए, मेरा SQLPerformance.com लेख देखें, उचित रूप से संगणित संगणित कॉलम

चूँकि प्रश्न में XML का उल्लेख किया गया है, एक गणना कॉलम और स्केलर फ़ंक्शन का उपयोग करके मूल्यों को बढ़ावा देने के विकल्प के रूप में, आप एक चुनिंदा XML इंडेक्स का उपयोग करके भी देख सकते हैं, जैसा कि आपने सिलेक्टिव XML इंडेक्स में लिखा है : नॉट बैड एट ऑल


10

@ पॉल के उत्कृष्ट हां # 1 के अलावा , वास्तव में हां # 2 है:

  • SQL सर्वर 2005 के रूप में वापस काम करता है,
  • ट्रेस ध्वज सेट करने की आवश्यकता नहीं है,
  • करता नहीं की आवश्यकता है कि गणना स्तंभ हो PERSISTED, और
  • (ट्रेस ध्वज 176 की आवश्यकता नहीं होने के कारण), निरंतर गणना किए गए कॉलम से मेल खाते अभिव्यक्ति को नहीं रोकता है

केवल कमियां (जहां तक ​​मैं बता सकता हूं) हैं:

  • Azure SQL डेटाबेस पर काम नहीं करता है (कम से कम अभी तक नहीं, हालांकि यह Amazon RDS SQL सर्वर के साथ-साथ Linux और SQL सर्वर पर भी काम करता है, और
  • कई DBA के कम्फर्ट ज़ोन से थोड़ा बाहर है

और यह विकल्प है: SQLCLR

ये सही है। SQLCLR स्केलर UDFs का एक अच्छा पहलू यह है कि, यदि वे कोई डेटा एक्सेस (न तो उपयोगकर्ता और न ही सिस्टम) करते हैं, तो वे समानता का निषेध नहीं करते हैं। और यह सिर्फ सिद्धांत या विपणन नहीं है। जबकि मेरे पास समय नहीं है (फिलहाल) पूरी तरह से विस्तृत लेखन-कार्य करने के लिए, मैंने यह परीक्षण और सिद्ध किया है।

मैंने निम्नलिखित ब्लॉग पोस्ट से प्रारंभिक सेटअप का उपयोग किया (उम्मीद है कि ओपी इसे एक अविश्वसनीय स्रोत नहीं मानता है):

खराब आइडिया जीन्स: मल्टीपल इंडेक्स संकेत

और निम्नलिखित परीक्षण किए:

  1. Ism समानांतरवाद (जैसा कि अपेक्षित है) के रूप में प्रारंभिक क्वेरी को दौड़ाएं
  2. ([c2] * [c3])(समानांतरवाद के रूप में परिभाषित एक गैर-निरंतर कम्प्यूटेड कॉलम जोड़ा गया (उम्मीद के मुताबिक)
  3. उस गणना किए गए कॉलम को हटा दिया और एक गैर-निरंतर कंप्यूटेड कॉलम जोड़ा, जो T-SQL स्केलर UDF (निर्मित SCHEMABINDING) के साथ RETURN (@First * @Second);a NO समानांतरवाद के रूप में परिभाषित किया गया था (जैसा कि अपेक्षित था)
  4. टी-एसक्यूएल यूडीएफ गणना वाले कॉलम को हटा दिया और एक गैर-निरंतर कम्प्यूटेड कॉलम जोड़ा गया जो SQLCLR स्केलर यूडीएफ (दोनों के साथ कोशिश की गई ) IsDeterministic = trueऔर ism समानांतरवाद (वू हू !!) के= false रूप में परिभाषित किया गया है return SqlInt32.Multiply(First, Second);

इसलिए, जबकि SQLCLR हर किसी के लिए काम नहीं करेगा, यह निश्चित रूप से उन लोगों / स्थितियों / वातावरण के लिए इसके फायदे हैं जो एक अच्छा फिट हैं। और, जैसा कि यह इस विशिष्ट प्रश्न से संबंधित है - XQuery का उपयोग करके दिए गए उदाहरण - यह निश्चित रूप से उसके लिए काम करेगा (और, विशेष रूप से क्या किया जा रहा है, इसके आधार पर, यह थोड़ा तेज हो सकता है)।

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