XML फ़ील्ड की उपस्थिति के कारण अधिकांश टेबल डेटा LOB_DATA पृष्ठों पर स्थित होता है (वास्तव में ~ टेबल पृष्ठों का 90% LOB_DATA है)।
केवल तालिका में XML कॉलम होने से इसका प्रभाव नहीं होता है। यह XML डेटा की उपस्थिति है, जो कुछ शर्तों के तहत , पंक्ति के डेटा के कुछ हिस्से को LOB_DATA पृष्ठों पर पंक्ति से संग्रहीत करने का कारण बनता है। और जब एक (या शायद कई ;-) यह तर्क दे सकता है कि XML
कॉलम का तात्पर्य है कि स्तंभ वास्तव में XML डेटा होगा, यह गारंटी नहीं है कि XML डेटा को पंक्ति से संग्रहीत करने की आवश्यकता होगी: जब तक कि पंक्ति बहुत पहले से ही भर नहीं जाती है किसी भी XML डेटा के बाहर, छोटे दस्तावेज़ (8000 बाइट तक) पंक्ति में फिट हो सकते हैं और कभी भी LOB_ATA डेटा पृष्ठ पर नहीं जाते हैं।
क्या मैं यह सोचने में सही हूं कि LOB_DATA पृष्ठ न केवल उनके आकार के कारण धीमी गति से स्कैन का कारण बन सकते हैं, बल्कि इसलिए भी क्योंकि SQL सर्वर तालिका में बहुत सारे LOB_DATA पृष्ठों के प्रभावी रूप से क्लस्टर इंडेक्स को स्कैन नहीं कर सकता है?
स्कैनिंग सभी पंक्तियों को देखने के लिए संदर्भित करता है। बेशक, जब कोई डेटा पृष्ठ पढ़ा जाता है, तो सभी इन-रो डेटा पढ़ा जाता है, भले ही आपने कॉलम का सबसेट चुना हो। LOB डेटा के साथ अंतर यह है कि यदि आप उस कॉलम का चयन नहीं करते हैं, तो ऑफ-रो डेटा पढ़ा नहीं जाएगा। इसलिए वास्तव में यह निष्कर्ष निकालना उचित नहीं है कि SQL सर्वर इस क्लस्टर इंडेक्स को कितनी कुशलता से स्कैन कर सकता है क्योंकि आपने वास्तव में इसका परीक्षण नहीं किया था (या आपने इसका आधा परीक्षण किया था)। आपने सभी कॉलम चुने, जिसमें XML कॉलम शामिल है, और जैसा कि आपने उल्लेख किया है, वह वह जगह है जहां अधिकांश डेटा स्थित है।
इसलिए हम पहले से ही जानते हैं कि SELECT TOP 1000 *
परीक्षण केवल एक पंक्ति में 8k डेटा पृष्ठों की एक श्रृंखला नहीं पढ़ रहा था, बल्कि प्रत्येक पंक्ति में अन्य स्थानों पर कूद रहा था । उस एलओबी डेटा की सटीक संरचना इस बात पर आधारित हो सकती है कि यह कितना बड़ा है। यहां दिखाए गए शोध के आधार पर (अधिकतम के लिए LOB पॉइंटर का आकार क्या है) प्रकार जैसे कि वर्चर, वर्ब, आदि। ), दो प्रकार के ऑफ-पंक्ति एलओबी आवंटन हैं:
- इनलाइन रूट - 8001 से 40,000 (वास्तव में 42,000) बाइट्स, अंतरिक्ष अनुमति के बीच के डेटा के लिए, 1 से 5 पॉइंटर्स (24 - 72 बाइट्स) होंगे जो सीधे LOB पेज (ओं) को इंगित करते हैं।
- TEXT_TREE - 42,000 से अधिक बाइट्स के डेटा के लिए, या यदि 1 से 5 पॉइंटर्स-इन-रो फिट नहीं हो सकते हैं, तो LOB पृष्ठों (यानी "के लिए पॉइंटर्स की सूची के शुरुआती पृष्ठ पर सिर्फ 24 बाइट पॉइंटर होगा।" text_tree "पेज)।
इन दो स्थितियों में से एक हर बार जब आप एलओबी डेटा प्राप्त करते हैं जो 8000 बाइट्स से अधिक होता है या सिर्फ इन-पंक्ति में फिट नहीं होता है। मैंने PasteBin.com ( LOB आवंटन और परीक्षण पढ़ने के लिए टी-एसक्यूएल स्क्रिप्ट ) पर एक परीक्षण स्क्रिप्ट पोस्ट की है जो 3 प्रकार के LOB आवंटन (डेटा के आकार के आधार पर) के साथ-साथ उनमें से प्रत्येक के तार्किक या प्रभाव पर असर दिखाता है। भौतिक पढ़ता है। आपके मामले में, यदि XML डेटा वास्तव में प्रति पंक्ति 42,000 बाइट्स से कम है, तो इसमें से कोई भी (या इसके बहुत कम) कम से कम कुशल TEXT_TREE संरचना में होना चाहिए।
यदि आप परीक्षण करना चाहते हैं कि SQL सर्वर उस क्लस्टर इंडेक्स को कितनी जल्दी स्कैन कर सकता है, SELECT TOP 1000
लेकिन उस XML कॉलम को शामिल न करते हुए एक या अधिक कॉलम निर्दिष्ट करें। यह आपके परिणामों को कैसे प्रभावित करता है? यह काफी तेज होना चाहिए।
क्या ऐसी तालिका संरचना / डेटा पैटर्न के लिए उचित माना जाता है?
यह देखते हुए कि हमारे पास वास्तविक तालिका संरचना और डेटा पैटर्न का अधूरा विवरण है, कोई भी उत्तर उन गुम विवरणों के आधार पर इष्टतम नहीं हो सकता है। इसे ध्यान में रखते हुए, मैं कहूंगा कि आपकी तालिका संरचना या डेटा पैटर्न के बारे में स्पष्ट रूप से अनुचित कुछ भी नहीं है।
मैं 20KB से ~ 2.5KB तक XML को (ac # ऐप में) संपीड़ित कर सकता हूं और LOB डेटा पृष्ठों के उपयोग को रोकने के लिए इसे VARBINARY कॉलम में संग्रहीत कर सकता हूं। यह गति मेरे परीक्षणों में 20x बार चयन करती है।
इसने सभी कॉलमों का चयन किया, या यहां तक कि सिर्फ XML डेटा (अब VARBINARY
) में तेजी से, लेकिन यह वास्तव में उन प्रश्नों को नुकसान पहुंचाता है जो "XML" डेटा का चयन नहीं करते हैं। मान लें कि आपके पास अन्य स्तंभों में लगभग 50 बाइट्स हैं और FILLFACTOR
100 में से एक है, तो:
कोई संपीड़न नहीं: 15k XML
डेटा में 2 LOB_DATA पृष्ठों की आवश्यकता होती है, जिसके लिए इनलाइन रूट के लिए 2 पॉइंटर्स की आवश्यकता होती है। पहला पॉइंटर 24 बाइट्स का है और दूसरा 12 का है, जिसमें XML डेटा के लिए कुल 36 बाइट्स हैं। कुल पंक्ति का आकार 86 बाइट्स है, और आप 8060 बाइट डेटा पेज पर उन पंक्तियों में से 93 को फिट कर सकते हैं। इसलिए, 1 मिलियन पंक्तियों के लिए 10,753 डेटा पृष्ठों की आवश्यकता होती है।
कस्टम संपीड़न: 2.5k VARBINARY
डेटा पंक्ति में फिट होगा। कुल पंक्ति का आकार 2610 (2.5 * 1024 = 2560) बाइट्स है, और आप 8060 बाइट डेटा पेज पर उन पंक्तियों में से केवल 3 को ही फिट कर सकते हैं। इसलिए, 1 मिलियन पंक्तियों के लिए 333,334 डेटा पृष्ठों की आवश्यकता होती है।
एर्गो, क्लस्टर्ड इंडेक्स के लिए डेटा पन्नों में 30 गुना वृद्धि में कस्टम संपीड़न परिणामों को लागू करता है । मतलब, क्लस्टर्ड इंडेक्स स्कैन का उपयोग करने वाले सभी प्रश्नों में अब पढ़ने के लिए लगभग 322,500 अधिक डेटा पृष्ठ हैं। कृपया इस प्रकार के कम्प्रेशन करने के अतिरिक्त रेमूलेशन के लिए नीचे विस्तृत सेक्शन देखें।
मैं के प्रदर्शन के आधार पर किसी भी रिफैक्टरिंग करने के खिलाफ सावधानी बरतूँगा SELECT TOP 1000 *
। यह एक क्वेरी होने की संभावना नहीं है कि आवेदन भी जारी करेगा, और संभावित अनावश्यक अनुकूलन (ओं) के लिए एकमात्र आधार के रूप में उपयोग नहीं किया जाना चाहिए।
अधिक विस्तृत जानकारी और अधिक परीक्षणों की कोशिश करने के लिए, कृपया नीचे अनुभाग देखें।
इस प्रश्न का निश्चित उत्तर नहीं दिया जा सकता है, लेकिन हम कम से कम कुछ प्रगति कर सकते हैं और अतिरिक्त शोध का सुझाव दे सकते हैं ताकि हमें सटीक मुद्दे का पता लगाने में मदद मिल सके (आदर्श रूप से साक्ष्य के आधार पर)।
हम क्या जानते हैं:
- तालिका में लगभग 1 मिलियन पंक्तियाँ हैं
- टेबल का आकार लगभग 15 जीबी है
- टेबल एक शामिल
XML
स्तंभ और प्रकार के कई अन्य स्तंभों: INT
, BIGINT
, UNIQUEIDENTIFIER
, "आदि"
XML
कॉलम "आकार" औसतन लगभग 15k है
- दौड़ने के बाद
DBCC DROPCLEANBUFFERS
, निम्नलिखित क्वेरी को पूरा करने में 20 - 25 सेकंड लगते हैं:SELECT TOP 1000 * FROM TABLE
- क्लस्टर सूचकांक को स्कैन किया जा रहा है
- क्लस्टर किए गए सूचकांक पर विखंडन 0% के करीब है
हम क्या सोचते हैं हम जानते हैं:
- इन प्रश्नों के बाहर कोई अन्य डिस्क गतिविधि नहीं। क्या आपको यकीन है? यहां तक कि अगर कोई अन्य उपयोगकर्ता प्रश्न नहीं हैं, तो क्या पृष्ठभूमि संचालन हो रहा है? क्या SQL सर्वर पर बाहरी प्रक्रियाएं एक ही मशीन पर चल रही हैं जो कुछ IO को ले जा सकती हैं? वहाँ नहीं हो सकता है, लेकिन यह पूरी तरह से प्रदान की गई जानकारी के आधार पर स्पष्ट नहीं है।
- 15 एमबी XML डेटा वापस किया जा रहा है। यह संख्या किस पर आधारित है? प्रति पंक्ति XML डेटा के औसत से 1000 पंक्तियों से प्राप्त अनुमान प्रति पंक्ति 15k है? या उस क्वेरी के लिए जो प्राप्त हुआ था उसका प्रोग्रामेटिक एकत्रीकरण? यदि यह केवल एक अनुमान है, तो मैं इस पर भरोसा नहीं करूंगा क्योंकि XML डेटा का वितरण उस तरह से भी नहीं हो सकता है जो एक साधारण औसत द्वारा निहित होता है।
XML संपीड़न मदद कर सकता है। आप .NET में कम्प्रेशन कैसे करेंगे? GZipStream या DeflateStream वर्ग के माध्यम से ? यह एक शून्य-लागत विकल्प नहीं है। यह निश्चित रूप से कुछ डेटा को बड़े प्रतिशत से संपीड़ित करेगा, लेकिन इसमें अधिक सीपीयू की भी आवश्यकता होगी क्योंकि आपको हर बार डेटा को संपीड़ित / डिकम्प्रेस करने के लिए एक अतिरिक्त प्रक्रिया की आवश्यकता होगी। यह योजना पूरी तरह से आपकी क्षमता को दूर कर देगी:
- क्वेरी के माध्यम से XML डेटा
.nodes
, .value
, .query
, और .modify
एक्सएमएल कार्य करता है।
XML डेटा को इंडेक्स करें।
कृपया ध्यान रखें (जब से आपने उल्लेख किया है कि XML "अत्यधिक अनावश्यक" है) कि XML
डेटाटाइप पहले से ही इसमें अनुकूलित है कि यह एक शब्दकोश में तत्व और विशेषता नामों को संग्रहीत करता है, प्रत्येक आइटम के लिए एक पूर्णांक सूचकांक आईडी निर्दिष्ट करता है, और फिर उस पूर्णांक आईडी का उपयोग करता है पूरे दस्तावेज़ में (इसलिए यह प्रत्येक उपयोग के अनुसार पूरा नाम नहीं दोहराता है, और न ही इसे तत्वों के समापन के रूप में फिर से दोहराता है)। वास्तविक डेटा में बाहरी सफेद स्थान भी हटा दिया गया है। यही कारण है कि एक्सएमएल दस्तावेज़ निकाले जाने से उनकी मूल संरचना बरकरार नहीं रहती है और खाली तत्व क्यों निकाले जाते हैं, <element />
भले ही वे अंदर गए हों<element></element>
। तो GZip (या कुछ और) के माध्यम से संपीड़ित करने से कोई भी लाभ केवल तत्व और / या विशेषता मानों को संपीड़ित करने से मिलेगा, जो कि एक बहुत छोटा सतह क्षेत्र है जिसे सबसे अधिक उम्मीद की जा सकती है, और सबसे अधिक संभावना है कि नुकसान के लायक नहीं है क्षमताओं के रूप में सीधे ऊपर उल्लेख किया है।
कृपया यह भी ध्यान रखें कि XML डेटा को संपीड़ित करने और VARBINARY(MAX)
परिणाम को संग्रहीत करने से LOB की पहुंच समाप्त नहीं होगी, यह इसे कम कर देगा। पंक्ति के शेष डेटा के आकार के आधार पर, संपीड़ित मान पंक्ति में फिट हो सकता है, या इसके लिए अभी भी LOB पृष्ठों की आवश्यकता हो सकती है।
यह जानकारी, जबकि उपयोगी है, लगभग पर्याप्त नहीं है। क्वेरी प्रदर्शन को प्रभावित करने वाले बहुत सारे कारक हैं, इसलिए हमें जो कुछ चल रहा है उसकी अधिक विस्तृत तस्वीर की आवश्यकता है।
हम क्या नहीं जानते, लेकिन इसके लिए आवश्यक है:
SELECT *
पदार्थ का प्रदर्शन क्यों होता है? क्या यह एक पैटर्न है जिसे आप कोड में उपयोग करते हैं। यदि हां, तो क्यों?
- केवल XML कॉलम के चयन का प्रदर्शन क्या है? क्या आँकड़े और समय यदि आप बस कर रहे हैं
SELECT TOP 1000 XmlColumn FROM TABLE;
:?
इन 1000 पंक्तियों को वापस करने में 20 - 25 सेकंड का समय नेटवर्क कारकों (वायर के पार डेटा प्राप्त करने) से संबंधित है, और क्लाइंट कारकों से कितना संबंधित है (प्रतिपादन है कि लगभग 15 एमबी प्लस बाकी गैर- एसएसएमएस में ग्रिड में एक्सएमएल डेटा, या संभवतः डिस्क पर बचत)?
ऑपरेशन के इन दो पहलुओं को बाहर निकालना कभी-कभी डेटा को वापस नहीं करने के द्वारा किया जा सकता है। अब, कोई अस्थायी तालिका या तालिका चर में चयन करने के लिए सोच सकता है, लेकिन यह सिर्फ कुछ नए चर (यानी डिस्क I / O के लिए tempdb
, लेन-देन लॉग लिखता है, tempdb डेटा और / या लॉग फ़ाइल की संभावित ऑटो-वृद्धि की आवश्यकता होगी बफ़र पूल में स्थान, आदि)। वे सभी नए कारक वास्तव में क्वेरी समय बढ़ा सकते हैं। इसके बजाय, मैं आमतौर पर स्तंभों को चर (उपयुक्त डेटाटाइप का; नहीं SQL_VARIANT
) में संग्रहीत करता हूं जो प्रत्येक नई पंक्ति (यानी SELECT @Column1 = tab.Column1,...
) के साथ ओवरराइट हो जाते हैं ।
हालांकि , के रूप में यह DBA.StackExchange क्यू एंड ए में @PaulWhite द्वारा बताया गया, तार्किक अलग पढ़ता है जब एक ही LOB डेटा तक पहुँचने pastebin पर पोस्ट मेरे अपने के अतिरिक्त अनुसंधान के साथ, ( टी SQL स्क्रिप्ट LOB पढ़ता के लिए विभिन्न परिदृश्यों का परीक्षण ) , LOBs लगातार के बीच पहुँचा नहीं कर रहे हैं SELECT
, SELECT INTO
, SELECT @XmlVariable = XmlColumn
, SELECT @XmlVariable = XmlColumn.query(N'/')
, और SELECT @NVarCharVariable = CONVERT(NVARCHAR(MAX), XmlColumn)
। तो हमारे विकल्प यहाँ कुछ अधिक सीमित हैं, लेकिन यहाँ वही किया जा सकता है:
- SSMS या SQLCMD.EXE में SQL सर्वर चलाने वाले सर्वर पर क्वेरी को निष्पादित करके नेटवर्क मुद्दों को नियमित करें।
- क्वेरी विकल्प -> परिणाम -> ग्रिड पर जाएं और "निष्पादन के बाद परिणामों को छोड़ें" के विकल्प की जांच करके SSMS में क्लाइंट मुद्दों को नियमबद्ध करें। कृपया ध्यान दें कि यह विकल्प संदेशों सहित सभी आउटपुट को रोक देगा, लेकिन प्रत्येक पंक्ति में मेमोरी को आवंटित करने और फिर इसे ग्रिड में ड्रा करने के लिए SSMS को लगने वाले समय को नियंत्रित करने के लिए उपयोगी हो सकता है।
वैकल्पिक रूप से, आप SQLCMD.EXE के माध्यम से क्वेरी को निष्पादित कर सकते हैं और आउटपुट को कहीं भी जाने के लिए निर्देशित कर सकते हैं -o NUL:
:।
- क्या इस क्वेरी से कोई प्रतीक्षा प्रकार जुड़ा हुआ है? यदि हाँ, तो वह प्रतीक्षा प्रकार क्या है?
वापस किए जा रहे कॉलम के लिए वास्तविक डेटा आकार क्या है ? संपूर्ण तालिका में उस स्तंभ का औसत आकार वास्तव में मायने नहीं रखता है यदि "TOP 1000" पंक्तियों में कुल डेटा का एक बड़ा हिस्सा हो । यदि आप TOP 1000 पंक्तियों के बारे में जानना चाहते हैं, तो उन पंक्तियों को देखें। कृपया निम्नलिखित चलाएं:XML
XML
SELECT TOP 1000 tab.*,
SUM(DATALENGTH(tab.XmlColumn)) / 1024.0 AS [TotalXmlKBytes],
AVG(DATALENGTH(tab.XmlColumn)) / 1024.0 AS [AverageXmlKBytes]
STDEV(DATALENGTH(tab.XmlColumn)) / 1024.0 AS [StandardDeviationForXmlKBytes]
FROM SchemaName.TableName tab;
- सटीक तालिका स्कीमा। कृपया सभी अनुक्रमणिका सहित पूरा
CREATE TABLE
विवरण प्रदान करें ।
- प्रश्न योजना? क्या ऐसा कुछ है जिसे आप पोस्ट कर सकते हैं? यह जानकारी शायद कुछ भी नहीं बदलेगी, लेकिन यह जानना बेहतर है कि यह अनुमान लगाने की तुलना में नहीं होगा कि यह गलत नहीं होगा;;
- क्या डेटा फ़ाइल पर भौतिक / बाहरी विखंडन है? हालांकि यह एक बड़ा कारक नहीं हो सकता है, क्योंकि आप "उपभोक्ता-ग्रेड एसएटीए" का उपयोग कर रहे हैं और एसएसडी या यहां तक कि सुपर-एक्सपेंसिव एसएटीए का उपयोग नहीं कर रहे हैं, उप-क्रमिक रूप से ऑर्डर किए गए सेक्टरों का प्रभाव अधिक ध्यान देने योग्य होगा, विशेष रूप से उन क्षेत्रों की संख्या के रूप में जिसे पढ़ने की आवश्यकता बढ़ जाती है।
निम्नलिखित क्वेरी के सटीक परिणाम क्या हैं :
SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(),
OBJECT_ID(N'dbo.SchemaName.TableName'), 1, 0, N'LIMITED');
अपडेट करें
मेरे साथ यह हुआ कि मुझे इस परिदृश्य को पुन: पेश करने की कोशिश करनी चाहिए कि क्या मैं समान व्यवहार का अनुभव करता हूं। इसलिए, मैंने कई स्तंभों के साथ एक तालिका बनाई (प्रश्न में अस्पष्ट वर्णन के समान), और फिर इसे 1 मिलियन पंक्तियों के साथ आबाद किया, और XML कॉलम में प्रति पंक्ति लगभग 15k डेटा है (नीचे कोड देखें)।
मैंने जो पाया वह यह है कि SELECT TOP 1000 * FROM TABLE
पहली बार 8 सेकंड में पूरा किया और उसके बाद 2 - 4 सेकंड हर बार (हाँ, क्वेरी के DBCC DROPCLEANBUFFERS
प्रत्येक रन से पहले निष्पादित SELECT *
)। और मेरा कई साल पुराना लैपटॉप तेज नहीं है: SQL Server 2012 SP2 डेवलपर संस्करण, 64 बिट, 6 जीबी रैम, दोहरी 2.5 Ghz कोर i5, और एक 5400 RPM SATA ड्राइव। मैं एसएसएमएस 2014, एसक्यूएल सर्वर एक्सप्रेस 2014, क्रोम, और कई अन्य चीजें भी चला रहा हूं।
मेरे सिस्टम के प्रतिक्रिया समय के आधार पर, मैं दोहराऊंगा कि हमें और अधिक जानकारी की आवश्यकता है (यानी तालिका और डेटा के बारे में, सुझाए गए परीक्षणों के परिणाम, आदि) के लिए 20 के कारण को कम करने में मदद करने के लिए - 25 सेकंड का प्रतिक्रिया समय जो आप देख रहे हैं।
SET ANSI_NULLS, NOCOUNT ON;
GO
IF (OBJECT_ID(N'dbo.XmlReadTest') IS NOT NULL)
BEGIN
PRINT N'Dropping table...';
DROP TABLE dbo.XmlReadTest;
END;
PRINT N'Creating table...';
CREATE TABLE dbo.XmlReadTest
(
ID INT NOT NULL IDENTITY(1, 1),
Col2 BIGINT,
Col3 UNIQUEIDENTIFIER,
Col4 DATETIME,
Col5 XML,
CONSTRAINT [PK_XmlReadTest] PRIMARY KEY CLUSTERED ([ID])
);
GO
DECLARE @MaxSets INT = 1000,
@CurrentSet INT = 1;
WHILE (@CurrentSet <= @MaxSets)
BEGIN
RAISERROR(N'Populating data (1000 sets of 1000 rows); Set # %d ...',
10, 1, @CurrentSet) WITH NOWAIT;
INSERT INTO dbo.XmlReadTest (Col2, Col3, Col4, Col5)
SELECT TOP 1000
CONVERT(BIGINT, CRYPT_GEN_RANDOM(8)),
NEWID(),
GETDATE(),
N'<test>'
+ REPLICATE(CONVERT(NVARCHAR(MAX), CRYPT_GEN_RANDOM(1), 2), 3750)
+ N'</test>'
FROM [master].[sys].all_columns sac1;
IF ((@CurrentSet % 100) = 0)
BEGIN
RAISERROR(N'Executing CHECKPOINT ...', 10, 1) WITH NOWAIT;
CHECKPOINT;
END;
SET @CurrentSet += 1;
END;
--
SELECT COUNT(*) FROM dbo.XmlReadTest; -- Verify that we have 1 million rows
-- O.P. states that the "clustered index fragmentation is close to 0%"
ALTER INDEX [PK_XmlReadTest] ON dbo.XmlReadTest REBUILD WITH (FILLFACTOR = 90);
CHECKPOINT;
--
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
SET STATISTICS IO, TIME ON;
SELECT TOP 1000 * FROM dbo.XmlReadTest;
SET STATISTICS IO, TIME OFF;
/*
Scan count 1, logical reads 21, physical reads 1, read-ahead reads 4436,
lob logical reads 5676, lob physical reads 1, lob read-ahead reads 3967.
SQL Server Execution Times:
CPU time = 171 ms, elapsed time = 8329 ms.
*/
और, क्योंकि हम गैर-एलओबी पृष्ठों को पढ़ने में लगने वाले समय को निकालना चाहते हैं, इसलिए मैंने सभी क्वेरी का चयन करने के लिए निम्न क्वेरी को चलाया लेकिन XML कॉलम (ऊपर दिए गए परीक्षणों में से एक)। यह 1.5 सेकंड में काफी लगातार लौटता है।
DBCC DROPCLEANBUFFERS WITH NO_INFOMSGS;
SET STATISTICS IO, TIME ON;
SELECT TOP 1000 ID, Col2, Col3, Col4 FROM dbo.XmlReadTest;
SET STATISTICS IO, TIME OFF;
/*
Scan count 1, logical reads 21, physical reads 1, read-ahead reads 4436,
lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 1666 ms.
*/
निष्कर्ष (फिलहाल के लिए)
अपने परिदृश्य को फिर से बनाने के मेरे प्रयास के आधार पर, मुझे नहीं लगता कि हम SATA ड्राइव या गैर-अनुक्रमिक I / O को 20 - 25 सेकंड के मुख्य कारण के रूप में इंगित कर सकते हैं, खासकर क्योंकि हम अभी भी एक्सएमएल कॉलम को शामिल न करने पर क्वेरी कितनी तेजी से लौटती है, यह नहीं जानते। और मैं बड़ी संख्या में पुन: पेश करने तार्किक पढ़ता की (गैर LOB) है कि आप दिखा रहे हैं सक्षम नहीं था, लेकिन मुझे लगता है कि मुझे लगता है कि के आलोक में प्रत्येक पंक्ति के लिए और अधिक डेटा जोड़ने की जरूरत है और के बयान:
~ 90% टेबल पेज LOB_DATA हैं
मेरी तालिका में 1 मिलियन पंक्तियाँ हैं, जिनमें से प्रत्येक में XML डेटा सिर्फ 15k से अधिक है, और sys.dm_db_index_physical_stats
दिखाता है कि 2 मिलियन LOB_DATA पृष्ठ हैं। शेष 10% तब 222k IN_ROW डेटा पृष्ठ होंगे, फिर भी मेरे पास केवल 11,630 हैं। इसलिए एक बार फिर, हमें वास्तविक तालिका स्कीमा और वास्तविक डेटा के बारे में अधिक जानकारी की आवश्यकता है।