हम रिलीज के बीच में हैं, जहां हम अभी तक किसी भी ऐसी सुविधा के बारे में नहीं सुन रहे हैं जिसके लिए योजना बनाई गई है SQL सर्वर vNext. जब तक हम वैध व्यावसायिक मामलों के साथ अपने अनुरोधों का समर्थन कर सकते हैं, तब तक सुधार के लिए Microsoft पर दबाव डालने का यह शायद सबसे अच्छा समय है। SQL सर्वर 2016 में, STRING_SPLIT
एक भाषा में एक लंबे समय से लापता अंतर को हल किया, जो कि, बेशक, जटिल स्ट्रिंग प्रसंस्करण के लिए अभिप्रेत नहीं था। और यही मैं आज लाना चाहता हूं।
SQL सर्वर 2016 से पहले के वर्षों के लिए (और उसके बाद के वर्षों के लिए), हमने अपने स्वयं के संस्करण लिखे हैं, समय के साथ उनमें सुधार किया है, और यहां तक कि तर्क दिया है कि किसका सबसे तेज़ था। हमने प्रत्येक माइक्रोसेकंड के बारे में ब्लॉग किया जो हम प्राप्त कर सकते थे और मैंने, एक के लिए, कई बार कहा है, "स्ट्रिंग्स को विभाजित करने के बारे में यह मेरी आखिरी पोस्ट है!" फिर भी हम यहाँ हैं।
मैं हमेशा तर्क दूंगा कि तालिका-मूल्यवान पैरामीटर अलग-अलग तारों को तोड़ने का सही तरीका है। लेकिन जब मैं विश्वास करें कि पाठ के इन अल्पविराम से अलग किए गए ब्लॉब्स को उस रूप में डेटाबेस के सामने कभी भी उजागर नहीं किया जाना चाहिए, बंटवारे के तार एक प्रचलित उपयोग का मामला बना हुआ है - मेरे कुछ ब्लॉग पोस्ट यहां शीर्ष 5 विचारों में हैं हर एक दिन ।
तो, बेहतर प्रतिस्थापन मौजूद होने पर लोग अभी भी टेबल-मूल्यवान कार्यों के साथ तारों को विभाजित करने का प्रयास क्यों कर रहे हैं? कुछ, मुझे यकीन है, क्योंकि वे अभी भी पुराने संस्करणों पर हैं, पुराने संगतता स्तर में फंस गए हैं, या तारों को विभाजित करने से बिल्कुल भी दूर नहीं हो सकते क्योंकि टीवीपी उनकी भाषा या ओआरएम द्वारा समर्थित नहीं हैं। बाकी के लिए, जबकि STRING_SPLIT
सुविधाजनक और कुशल दोनों है, यह सही नहीं है। इसमें ऐसे प्रतिबंध हैं जो कुछ घर्षण करते हैं और जो मौजूदा फ़ंक्शन कॉल को देशी कॉल के साथ बदलना या तो बोझिल या असंभव बनाते हैं।
यहां मेरी सूची है।
ये सीमाएं संपूर्ण नहीं हैं, लेकिन मैंने my . में महत्वपूर्ण सीमाएं सूचीबद्ध की हैं प्राथमिकता आदेश (और एंडी मॉलन ने आज भी इस बारे में ब्लॉग किया है):
- एकल वर्ण सीमांकक
ऐसा लगता है कि फ़ंक्शन केवल मृत-सरल उपयोग के मामले को ध्यान में रखकर बनाया गया था:सीएसवी। लोगों के पास1,2,3
. की तुलना में अधिक जटिल तार होते हैं याA|B|C
, और उन्हें अक्सर उनके नियंत्रण से बाहर के सिस्टम से उनके डेटाबेस में फीड किया जाता है। जैसा कि मैंने इस उत्तर और इस टिप में वर्णन किया है, इसके आसपास काम करने के तरीके हैं (वास्तव में अक्षम प्रतिस्थापन संचालन), लेकिन वे वास्तव में बदसूरत हैं और, स्पष्ट रूप से, मूल कार्यान्वयन द्वारा दिए गए सभी प्रदर्शन लाभों को पूर्ववत करें। इसके अलावा, इसके साथ कुछ घर्षण विशेष रूप से नीचे आता है:"ठीक है, PostgreSQL काstring_to_array
एकाधिक वर्ण सीमांकक को संभालता है, तो SQL सर्वर क्यों नहीं कर सकता?"कार्यान्वयन:separator
का अधिकतम आकार बढ़ाएँ . - इनपुट आदेश का कोई संकेत नहीं
फ़ंक्शन का आउटपुट एक सेट है और, स्वाभाविक रूप से, सेट का कोई क्रम नहीं होता है। और ज्यादातर मामलों में आपको एक इनपुट स्ट्रिंग दिखाई देगी जैसेbob,ted,frank
उसी क्रम में बाहर आएं (bob
ted
frank
), कोई गारंटी नहीं है (मैला के साथ या बिना(ORDER BY (SELECT NULL))
हैक)। कई घर-निर्मित कार्यों में स्ट्रिंग में क्रमिक स्थिति को इंगित करने के लिए एक आउटपुट कॉलम शामिल होता है, जो महत्वपूर्ण हो सकता है यदि सूची को एक परिभाषित क्रम में व्यवस्थित किया गया है या सटीक क्रमिक स्थिति का कुछ महत्व है। कार्यान्वयन:क्रमिक स्थिति कॉलम को शामिल करने के लिए एक विकल्प जोड़ें। उत्पादन। - आउटपुट प्रकार केवल इनपुट पर आधारित होता है
फ़ंक्शन का आउटपुट कॉलम या तोvarchar
. पर तय होता है याnvarchar
, और संपूर्ण इनपुट स्ट्रिंग की लंबाई द्वारा सटीक रूप से निर्धारित किया जाता है, न कि सबसे लंबे तत्व की लंबाई से। तो, आपके पास 25 अक्षरों की सूची है, आउटपुट प्रकार कम से कम . हैvarchar(51)
. लंबे समय तक तारों के लिए, यह उपयोग के आधार पर स्मृति अनुदान के मुद्दों को कम कर सकता है, और यदि उपभोक्ता किसी अन्य डेटा प्रकार आउटपुट पर निर्भर करता है (कहें,int
) पर निर्भर करता है तो समस्याएं पेश कर सकता है , जो बाद में निहित रूपांतरणों से बचने के लिए कभी-कभी निर्दिष्ट कार्य करता है)। वर्कअराउंड के रूप में, उपयोगकर्ता कभी-कभी अपनी स्वयं की अस्थायी तालिका या तालिका चर बनाते हैं, और इसके साथ बातचीत करने से पहले फ़ंक्शन के आउटपुट को डंप करते हैं, जिससे प्रदर्शन संबंधी समस्याएं हो सकती हैं। कार्यान्वयन:आउटपुट प्रकार को निर्दिष्ट करने के लिए एक विकल्प जोड़ेंvalue
. - खाली तत्वों या अनुगामी सीमांकक को अनदेखा नहीं कर सकता
जब आपके पासa,,,b,
. जैसी स्ट्रिंग हो , आप उम्मीद कर सकते हैं कि केवल दो तत्व आउटपुट होंगे, क्योंकि अन्य तीन खाली हैं। मैंने देखा है कि अधिकांश कस्टम टीवीएफ पिछली सीमांकक को ट्रिम कर देते हैं और/या शून्य-लंबाई वाले स्ट्रिंग्स को फ़िल्टर करते हैं, लेकिनSTRING_SPLIT
सभी 5 पंक्तियों को लौटाता है। इससे नेटिव फंक्शन में स्वैप करना मुश्किल हो जाता है क्योंकि आपको इन एंटिटीज को खत्म करने के लिए रैपिंग लॉजिक भी जोड़ना होगा। इम्प्लीमेंटेशन:खाली तत्वों को नजरअंदाज करने के लिए एक विकल्प जोड़ें। - डुप्लिकेट फ़िल्टर नहीं कर सकते
यह शायद कम आम अनुरोध है, औरDISTINCT
का उपयोग करके हल करना आसान है याGROUP BY
, लेकिन बहुत सारे फ़ंक्शन आपके लिए इसे स्वचालित रूप से करते हैं। इन मामलों में प्रदर्शन में कोई वास्तविक अंतर नहीं है, लेकिन अगर ऐसा कुछ है जिसे आप स्वयं जोड़ना भूल जाते हैं (एक बड़ी सूची के बारे में सोचें, जिसमें बहुत सारे डुप्लिकेट हों, एक बड़ी तालिका में शामिल हों)। कार्यान्वयन:डुप्लिकेट को फ़िल्टर करने के लिए एक विकल्प जोड़ें।
व्यवसाय का मामला यह है।
वे सभी सैद्धांतिक लगते हैं, लेकिन यहां व्यावसायिक मामला है, जो मैं आपको आश्वस्त कर सकता हूं कि यह बहुत वास्तविक है। वेफेयर में, हमारे पास एक पर्याप्त SQL सर्वर संपत्ति है, और हमारे पास सचमुच दर्जनों अलग-अलग टीमें हैं जिन्होंने वर्षों में अपने स्वयं के टेबल-मूल्यवान फ़ंक्शन बनाए हैं। कुछ दूसरों की तुलना में बेहतर हैं, लेकिन उन सभी को कोड की हजारों और हजारों पंक्तियों से बुलाया जाता है। हमने हाल ही में एक प्रोजेक्ट शुरू किया है जहां हम उन्हें STRING_SPLIT
. पर कॉल से बदलने की कोशिश कर रहे हैं , लेकिन हम मामलों को अवरुद्ध करने में भाग गए उपरोक्त सीमाओं में से कई शामिल हैं।
रैपर फ़ंक्शन का उपयोग करके कुछ को काम करना आसान होता है। लेकिन एकल वर्ण सीमांकक सीमा ने हमें REPLACE
. का उपयोग करके भयानक समाधान का मूल्यांकन करने के लिए मजबूर किया , और यह हमारे द्वारा अपेक्षित प्रदर्शन लाभ को समाप्त करने के लिए साबित हुआ, जिससे हम ब्रेक पंप कर रहे थे। और उन मामलों में, हमने संगतता स्तर में उन्नयन के लिए एक महत्वपूर्ण सौदेबाजी चिप को खो दिया (सभी डेटाबेस 130 पर नहीं हैं, 140 पर कोई बात नहीं)। उन मामलों में, हम न केवल STRING_SPLIT
. से हार रहे हैं सुधार, लेकिन अन्य 130+ प्रदर्शन सुधारों पर भी हमें आनंद मिलेगा यदि STRING_SPLIT
संगत स्तर के उन्नयन के लिए जोर देने के लिए अपने आप में पर्याप्त रूप से मजबूर कर रहा था।
तो, मैं आपकी मदद माँग रहा हूँ।
कृपया इस फ़ीडबैक आइटम पर जाएं:
- STRING_SPLIT सुविधा पूर्ण नहीं है
वोट दें! इससे भी महत्वपूर्ण बात, एक टिप्पणी छोड़ें आपके पास वास्तविक उपयोग के मामलों का वर्णन करना जो STRING_SPLIT
बनाते हैं आपके लिए एक दर्द या गैर-स्टार्टर। अकेले वोट पर्याप्त नहीं हैं, लेकिन पर्याप्त ठोस और गुणात्मक प्रतिक्रिया के साथ, एक मौका है कि वे इन अंतरालों को गंभीरता से लेना शुरू कर सकते हैं।
मुझे लगता है कि मल्टी-कैरेक्टर डिलीमीटर (यहां तक कि, [n]varchar(1)
से विस्तार करना) का समर्थन करना पसंद है से [n]varchar(5)
) एक अनियंत्रित सुधार है जो मेरे परिदृश्य को साझा करने वाले कई लोगों को अनवरोधित कर देगा। अन्य संवर्द्धन को लागू करना कठिन हो सकता है, कुछ को अधिभार और/या भाषा संवर्द्धन की आवश्यकता होती है, इसलिए मैं vNext में इन सभी सुधारों की अपेक्षा नहीं करता। लेकिन एक छोटा सा सुधार भी दोहराएगा कि STRING_SPLIT
एक सार्थक निवेश था, और यह कि इसे छोड़ा नहीं जा रहा है (जैसे, कहते हैं, निहित डेटाबेस, अधिक प्रसिद्ध ड्राइव-बाय सुविधाओं में से एक)।
सुनने के लिए धन्यवाद!