सेट अप:
create table dbo.T
(
ID int identity primary key,
XMLDoc xml not null
);
insert into dbo.T(XMLDoc)
select (
select N.Number
for xml path(''), type
)
from (
select top(10000) row_number() over(order by (select null)) as Number
from sys.columns as c1, sys.columns as c2
) as N;
प्रत्येक पंक्ति के लिए नमूना XML:
<Number>314</Number>
क्वेरी के लिए कार्य T
निर्दिष्ट मान के साथ पंक्तियों की संख्या को गिनना है <Number>
।
ऐसा करने के दो स्पष्ट तरीके हैं:
select count(*)
from dbo.T as T
where T.XMLDoc.value('/Number[1]', 'int') = 314;
select count(*)
from dbo.T as T
where T.XMLDoc.exist('/Number[. eq 314]') = 1;
यह पता चला कि value()
और exists()
काम करने के लिए चयनात्मक XML सूचकांक के लिए दो अलग-अलग पथ परिभाषाओं की आवश्यकता है।
create selective xml index SIX_T on dbo.T(XMLDoc) for
(
pathSQL = '/Number' as sql int singleton,
pathXQUERY = '/Number' as xquery 'xs:double' singleton
);
sql
संस्करण के लिए है value()
और xquery
संस्करण के लिए है exist()
।
आप सोच सकते हैं कि इस तरह का एक सूचकांक आपको एक अच्छी तलाश के साथ एक योजना देगा लेकिन चयनात्मक XML इंडेक्स को सिस्टम टेबल के प्राथमिक कुंजी के साथ सिस्टम टेबल के प्रमुख कुंजी के T
रूप में लागू किया जाता है । निर्दिष्ट पथ उस तालिका में विरल स्तंभ हैं। यदि आप परिभाषित रास्तों के वास्तविक मूल्यों का एक सूचकांक चाहते हैं, तो आपको प्रत्येक पथ अभिव्यक्ति के लिए एक माध्यमिक चयनात्मक सूचकांक बनाने की आवश्यकता है।
create xml index SIX_T_pathSQL on dbo.T(XMLDoc)
using xml index SIX_T for (pathSQL);
create xml index SIX_T_pathXQUERY on dbo.T(XMLDoc)
using xml index SIX_T for (pathXQUERY);
exist()
सिलेक्टिव XML इंडेक्स के लिए सिस्टम टेबल में एक महत्वपूर्ण लुकअप के बाद सेकेंडरी एक्सएमएल इंडेक्स में एक खोज की क्वेरी प्लान करता है (न जाने क्यों इसकी जरूरत है) और अंतिम रूप T
से यह सुनिश्चित करने के लिए इसमें लुकअप होता है कि वास्तव में हैं वहाँ पंक्तियाँ। अंतिम भाग आवश्यक है क्योंकि सिस्टम टेबल के बीच कोई विदेशी कुंजी बाधा नहीं है और T
।
value()
क्वेरी के लिए योजना इतनी अच्छी नहीं है। यह T
नेस्टर्ड लूप्स के साथ एक क्लस्टर्ड इंडेक्स स्कैन करता है, जो कि स्पार्स कॉलम से वैल्यू पाने के लिए इंटरनल टेबल पर एक सीक के साथ जुड़ता है और आखिर में वैल्यू पर फिल्टर करता है।
यदि एक चयनात्मक सूचकांक का उपयोग किया जाना चाहिए या अनुकूलन से पहले तय नहीं किया गया है, लेकिन द्वितीयक चयनात्मक सूचकांक का उपयोग किया जाना चाहिए या नहीं, यह अनुकूलनकर्ता द्वारा लागत आधारित निर्णय है।
जहां क्लॉज फिल्टर होता है, वहां माध्यमिक चयनात्मक सूचकांक का उपयोग क्यों नहीं किया जाता है value()
?
अपडेट करें:
प्रश्न शब्दार्थ से भिन्न हैं। यदि आप मान के साथ एक पंक्ति जोड़ते हैं
<Number>313</Number>
<Number>314</Number>`
exist()
संस्करण 2 पंक्तियाँ जाएगी और values()
क्वेरी 1 पंक्ति में गिना जाएगा। लेकिन इंडेक्स परिभाषाओं के साथ जैसा कि वे यहां निर्दिष्ट हैं, singleton
निर्देश SQL सर्वर का उपयोग करके आपको कई <Number>
तत्वों के साथ एक पंक्ति को जोड़ने से रोका जाएगा ।
हालांकि , संकलक की गारंटी के values()
बिना फ़ंक्शन का उपयोग करने की अनुमति नहीं [1]
देता है कि हम केवल एक ही मूल्य प्राप्त करेंगे। यही कारण [1]
है कि हमारे पास value()
योजना में एक टॉप एन सॉर्ट है ।
लगता है कि मैं यहाँ एक उत्तर पर बंद कर रहा हूँ ...