यह हाल ही में जिस तरह से सामना करना पड़ा, यह एक समान समस्या है। मुझे उन पंक्तियों से चयन करने की आवश्यकता थी जो प्राथमिक पंक्तियों की एक बड़ी सूची को छेड़छाड़ करते थे। प्रश्न यह था कि एसक्यूएल सर्वर को चाबियों की बड़ी सूची को एक ऐसे रूप में प्रभावी ढंग से कैसे भेजा जाए जो उपयोग करने के लिए तेज़ और प्रभावशाली है।
इस प्रकार की स्थिति के लिए वास्तव में क्या काम करता है एक्सएमएल डेटा प्रकार है। यदि आप संग्रहीत प्रक्रिया बनाते हैं जो एक्सएमएल प्रकार के एक पैरामीटर लेता है, तो आप इनपुट को एक्सएमएल खंड में पूर्व-स्वरूपित कर सकते हैं। उदाहरण के लिए, मान लीजिए कि एक्सएमएल टुकड़ा इस तरह दिखेगा करते हैं:
<a>
<b>1</b>
<b>3</b>
<b>7</b>
<b>14</b>
<b>147</b>
</a>
मैं तत्वों लघु नाम दिया था ("एक" और "बी"), क्योंकि एक लंबे समय तक नाम ग्राहक से करने के लिए प्रसारित करने के लिए और अधिक बाइट्स का मतलब होगा एसक्यूएल सर्वर। यहाँ कैसे आप एक रिकॉर्ड सेट के रूप में "बी" तत्वों की सभी सामग्री का चयन होता है:
declare @x xml
set @x = '<a><b>1</b><b>3</b><b>7</b><b>14</b><b>147</b></a>'
select t.item.value('.', 'int') from @x.nodes('//a/b') as t(item)
हालांकि वाक्य रचना गुप्त है, एक्सएमएल प्रकार सिर्फ एक मेज की तरह पूछे जा सकता है। अब आपको देखना चाहिए कि यह कहां जा रहा है। हम एक मेज की तरह एक्सएमएल प्रकार क्वेरी कर सकते हैं, हम एक और टेबल के साथ कि एक दूसरे को काटना कर सकते हैं:
select * from MyTable where ID in
(select t.item.value('.', 'int') from @x.nodes('//a/b') as t(item))
या का उपयोग कर एक में शामिल होने के
;with cte as
(select ID = t.item.value('.', 'int') from @x.nodes('//a/b') as t(item))
select * from MyTable inner join cte on MyTable.ID = cte.ID
आप दोनों संस्करणों को चलाने के लिए देखने के लिए जो तेजी के लिए किया जाएगा की जरूरत है आपका डेटा। मुझे लगता है कि जॉइन मेरे डेटा के साथ तेजी से काम करता है। यहाँ एक संग्रहीत प्रक्रिया है कि इनपुट के रूप में एक्सएमएल प्रकार लेता है और वापस थूक हमारे चयनित पंक्तियों है:
create procedure MyProc @x xml as
begin
set nocount on
;with cte as
(select ID = t.item.value('.', 'int') from @x.nodes('//a/b') as t(item))
select * from MyTable inner join cte on Table.ID = cte.ID
end
नई संग्रहीत प्रक्रिया का एक नमूना कॉल:
exec MyProc '<a><b>1</b><b>3</b><b>7</b><b>14</b><b>147</b></a>'
मैंने यह भी पाया है कि एक XML स्कीमा जोड़ने इनपुट खंड के लिए संग्रहीत प्रक्रिया को थोड़ा तेज़ करने में मदद मिली। मैं यहां एक्सएमएल स्कीमा के विवरण में नहीं जाऊंगा, लेकिन विचार एसक्यूएल को पहले से बताना है कि एक्सएमएल टुकड़ा कैसा दिखता है।
create xml schema collection MyInputSchema as
'<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="a">
<xsd:complexType>
<xsd:complexContent>
<xsd:restriction base="xsd:anyType">
<xsd:sequence>
<xsd:element name="b" type="xsd:integer" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>'
अब हम इनपुट के साथ इस स्कीमा हमारे संग्रहीत प्रक्रिया के लिए इस तरह संबद्ध कर सकते हैं: यहाँ कैसे हम इनपुट हमारे स्कीमा करेंगे
create procedure MyProc @x xml(MyInputSchema) as
begin
set nocount on
;with cte as
(select ID = t.item.value('.', 'int') from @x.nodes('//a/b') as t(item))
select * from MyTable inner join cte on Table.ID = cte.ID
end
जगह में यह सब के साथ
, मैं एक भेजने में सक्षम थे मेरे क्लाइंट मशीन से SQL सर्वर तक 43,016 वर्णों का एक्सएमएल खंड और परिणामस्वरूप बहुत जल्दी परिणाम प्राप्त करें। मैंने कुल 10,000 अनुरोधों के लिए 10 धागे पर 1,000 अनुरोधों का परीक्षण किया। परिणाम प्रति सेकंड संसाधित 72 अनुरोध थे। बेशक आपकी मिलेज आपके हार्डवेयर और सॉफ्टवेयर के आधार पर अलग-अलग हो जाएगी।
नोट: यह कोड SQL 2005 पर काम करता है और 2008 पर भी काम करना चाहिए।
यहां भी एक तालिका चर का उपयोग कर सकता है –