जोड़: SQL सर्वर 2012 इस क्षेत्र में कुछ बेहतर प्रदर्शन दिखाता है, लेकिन नीचे दिए गए विशिष्ट मुद्दों से निपटने के लिए प्रतीत नहीं होता है। यह
SQL सर्वर 2012 के बाद अगले प्रमुख संस्करण में स्पष्ट रूप से तय किया जाना चाहिए !
आपकी योजना से पता चलता है कि एकल आवेषण पैरामीटर वाली प्रक्रियाओं (संभवतः ऑटो मानकीकृत) का उपयोग कर रहे हैं, इसलिए इन के लिए पार्स / संकलन समय न्यूनतम होना चाहिए।
मैंने सोचा कि मैं इसे थोड़ा और देखूंगा, हालांकि एक लूप सेट किया है ( स्क्रिप्ट ) और VALUES
क्लॉज़ की संख्या को समायोजित करने और संकलन समय को रिकॉर्ड करने की कोशिश की गई ।
मैंने तब प्रति संकलन औसत समय प्राप्त करने के लिए पंक्तियों की संख्या से संकलन समय को विभाजित किया। परिणाम नीचे हैं
250 तक VALUES
खंडों संकलन समय / संख्याओं की संख्या एक मामूली प्रवृत्ति है, लेकिन कुछ भी नाटकीय नहीं है।
लेकिन फिर अचानक बदलाव आ जाता है।
डेटा का वह भाग नीचे दिखाया गया है।
+------+----------------+-------------+---------------+---------------+
| Rows | CachedPlanSize | CompileTime | CompileMemory | Duration/Rows |
+------+----------------+-------------+---------------+---------------+
| 245 | 528 | 41 | 2400 | 0.167346939 |
| 246 | 528 | 40 | 2416 | 0.162601626 |
| 247 | 528 | 38 | 2416 | 0.153846154 |
| 248 | 528 | 39 | 2432 | 0.157258065 |
| 249 | 528 | 39 | 2432 | 0.156626506 |
| 250 | 528 | 40 | 2448 | 0.16 |
| 251 | 400 | 273 | 3488 | 1.087649402 |
| 252 | 400 | 274 | 3496 | 1.087301587 |
| 253 | 400 | 282 | 3520 | 1.114624506 |
| 254 | 408 | 279 | 3544 | 1.098425197 |
| 255 | 408 | 290 | 3552 | 1.137254902 |
+------+----------------+-------------+---------------+---------------+
कैश्ड प्लान का आकार, जो रैखिक रूप से अचानक बढ़ रहा था, लेकिन CompileTime 7 गुना और CompileMemory शूट बढ़ाता है। यह योजना के बीच का कट ऑफ पॉइंट है जो एक ऑटो पैरामीरिडेड एक (1,000 मापदंडों के साथ) एक गैर पैरामीरिजेड के साथ है। इसके बाद, यह रैखिक रूप से कम कुशल (एक निश्चित समय में संसाधित मूल्य खंडों की संख्या के संदर्भ में) लगता है।
यकीन नहीं होता कि ऐसा क्यों होना चाहिए। संभवतः जब यह विशिष्ट शाब्दिक मूल्यों के लिए एक योजना को संकलित कर रहा है तो उसे कुछ गतिविधि करनी चाहिए जो रैखिक रूप से पैमाने पर नहीं होती है (जैसे कि छंटाई)।
यह कैश्ड क्वेरी योजना के आकार को प्रभावित करने के लिए नहीं लगता है जब मैंने एक क्वेरी पूरी तरह से डुप्लिकेट पंक्तियों से मिलकर बनाई थी और न ही स्थिरांक तालिका के उत्पादन के क्रम को प्रभावित करता है (और जैसा कि आप एक ढेर समय में डाल रहे हैं छँटाई में बिताए गए वैसे भी निरर्थक होगा भले ही यह किया हो)।
इसके अलावा अगर एक संकुल सूचकांक तालिका में जोड़ा जाता है, तो योजना अभी भी एक स्पष्ट प्रकार का कदम दिखाती है, इसलिए यह समय पर एक प्रकार से बचने के लिए संकलन समय पर छंटाई नहीं लगती है।
मैंने डिबगर में इसे देखने की कोशिश की, लेकिन SQL Server 2008 के मेरे संस्करण के लिए सार्वजनिक प्रतीक उपलब्ध नहीं हैं, इसलिए इसके बजाय मुझे UNION ALL
SQL सर्वर 2005 में इसके बराबर निर्माण को देखना पड़ा ।
एक विशिष्ट स्टैक ट्रेस नीचे है
sqlservr.exe!FastDBCSToUnicode() + 0xac bytes
sqlservr.exe!nls_sqlhilo() + 0x35 bytes
sqlservr.exe!CXVariant::CmpCompareStr() + 0x2b bytes
sqlservr.exe!CXVariantPerformCompare<167,167>::Compare() + 0x18 bytes
sqlservr.exe!CXVariant::CmpCompare() + 0x11f67d bytes
sqlservr.exe!CConstraintItvl::PcnstrItvlUnion() + 0xe2 bytes
sqlservr.exe!CConstraintProp::PcnstrUnion() + 0x35e bytes
sqlservr.exe!CLogOp_BaseSetOp::PcnstrDerive() + 0x11a bytes
sqlservr.exe!CLogOpArg::PcnstrDeriveHandler() + 0x18f bytes
sqlservr.exe!CLogOpArg::DeriveGroupProperties() + 0xa9 bytes
sqlservr.exe!COpArg::DeriveNormalizedGroupProperties() + 0x40 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x18a bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!COptExpr::DeriveGroupProperties() + 0x146 bytes
sqlservr.exe!CQuery::PqoBuild() + 0x3cb bytes
sqlservr.exe!CStmtQuery::InitQuery() + 0x167 bytes
sqlservr.exe!CStmtDML::InitNormal() + 0xf0 bytes
sqlservr.exe!CStmtDML::Init() + 0x1b bytes
sqlservr.exe!CCompPlan::FCompileStep() + 0x176 bytes
sqlservr.exe!CSQLSource::FCompile() + 0x741 bytes
sqlservr.exe!CSQLSource::FCompWrapper() + 0x922be bytes
sqlservr.exe!CSQLSource::Transform() + 0x120431 bytes
sqlservr.exe!CSQLSource::Compile() + 0x2ff bytes
तो स्टैक ट्रेस में नामों को छोड़ना स्ट्रिंग्स की तुलना में बहुत समय बिताना प्रतीत होता है।
यह KB आलेख इंगित करता है कि क्वेरी प्रसंस्करण DeriveNormalizedGroupProperties
के सामान्यीकरण चरण कहा जाता है के साथ जुड़ा हुआ है
इस चरण को अब बाध्यकारी या बीजगणित कहा जाता है और यह पिछले पार्स चरण से अभिव्यक्ति पार्स ट्री आउटपुट लेता है और इस मामले में अनुकूलन (तुच्छ योजना अनुकूलन) के लिए आगे बढ़ने के लिए एक अल्जीब्रीड अभिव्यक्ति ट्री (क्वेरी प्रोसेसर ट्री) को आउटपुट करता है [रेफ] ।
मैंने एक और प्रयोग ( स्क्रिप्ट ) की कोशिश की, जो मूल परीक्षण को फिर से चलाने के लिए था, लेकिन तीन अलग-अलग मामलों को देख रहा था।
- प्रथम नाम और अंतिम नाम स्ट्रिंग्स की लंबाई 10 वर्ण बिना डुप्लिकेट के।
- प्रथम नाम और अंतिम नाम स्ट्रिंग्स की लंबाई 50 अक्षर जिसमें कोई डुप्लिकेट नहीं है।
- सभी डुप्लिकेट के साथ लंबाई 10 अक्षर का पहला नाम और अंतिम नाम।
यह स्पष्ट रूप से देखा जा सकता है कि बदतर चीजें जितनी लंबी होती हैं और उतनी ही बेहतर चीजों को दोहराती हैं। जैसा कि पहले उल्लेख डुप्लिकेट कैश्ड प्लान आकार को प्रभावित नहीं करता है, इसलिए मुझे लगता है कि बीजगणित अभिव्यक्ति पेड़ का निर्माण करते समय डुप्लिकेट पहचान की एक प्रक्रिया होनी चाहिए।
संपादित करें
एक जगह जहां यह जानकारी लीवरेज की गई है, यहां @Lieven द्वारा दिखाई गई है
SELECT *
FROM (VALUES ('Lieven1', 1),
('Lieven2', 2),
('Lieven3', 3))Test (name, ID)
ORDER BY name, 1/ (ID - ID)
क्योंकि संकलन के समय में यह निर्धारित किया जा सकता है कि Name
स्तंभ की कोई डुप्लिकेट नहीं है, यह 1/ (ID - ID)
रन टाइम के दौरान द्वितीयक अभिव्यक्ति द्वारा आदेश देने वाली स्कीप को छोड़ देता है (योजना में छंटनी का केवल एक ORDER BY
कॉलम होता है) और शून्य त्रुटि से विभाजित नहीं किया जाता है। यदि डुप्लिकेट तालिका में जोड़े जाते हैं तो सॉर्ट ऑपरेटर कॉलम द्वारा दो ऑर्डर दिखाता है और अपेक्षित त्रुटि उठाई जाती है।