एक बहुत ही समान समस्या होने पर इस प्रश्न में ठोकर खाई, मैं अंत में हार मानने से पहले लगभग 3.5 ~ 4 घंटे के लिए 7.5MB XML फ़ाइल (~ लगभग 10,000 नोड्स) को संसाधित करने वाली क्वेरी चला रहा था।
हालांकि, थोड़ा और शोध करने के बाद मैंने पाया कि स्कीमा का उपयोग करके एक्सएमएल टाइप करने और एक्सएमएल इंडेक्स (मैं एक टेबल में थोक में डाला गया) बनाया है, वही क्वेरी ~ 0.04ms में पूरी हुई है।
प्रदर्शन में सुधार के लिए यह कैसा है!
स्कीमा बनाने के लिए कोड:
IF EXISTS ( SELECT * FROM sys.xml_schema_collections where [name] = 'MyXmlSchema')
DROP XML SCHEMA COLLECTION [MyXmlSchema]
GO
DECLARE @MySchema XML
SET @MySchema =
(
SELECT * FROM OPENROWSET
(
BULK 'C:\Path\To\Schema\MySchema.xsd', SINGLE_CLOB
) AS xmlData
)
CREATE XML SCHEMA COLLECTION [MyXmlSchema] AS @MySchema
GO
टाइप किए गए XML कॉलम के साथ तालिका बनाने के लिए कोड:
CREATE TABLE [dbo].[XmlFiles] (
[Id] [uniqueidentifier] NOT NULL,
-- Data from CV element
[Data] xml(CONTENT dbo.[MyXmlSchema]) NOT NULL,
CONSTRAINT [PK_XmlFiles] PRIMARY KEY NONCLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
इंडेक्स बनाने के लिए कोड
CREATE PRIMARY XML INDEX PXML_Data
ON [dbo].[XmlFiles] (Data)
हालांकि कुछ बातों को ध्यान में रखना है। SQL सर्वर का स्कीमा का कार्यान्वयन xsd का समर्थन नहीं करता:शामिल करें। इसका मतलब यह है कि यदि आपके पास एक स्कीमा है जो अन्य स्कीमा को संदर्भित करता है, तो आपको इन सभी को एक ही स्कीमा में कॉपी करना होगा और उसे जोड़ना होगा।
साथ ही मुझे एक त्रुटि मिलेगी:
XQuery [dbo.XmlFiles.Data.value()]: Cannot implicitly atomize or apply 'fn:data()' to complex content elements, found type 'xs:anyType' within inferred type 'element({http://www.mynamespace.fake/schemas}:SequenceNumber,xs:anyType) ?'.
अगर मैंने नोड के ऊपर नेविगेट करने का प्रयास किया तो मैंने नोड्स फ़ंक्शन के साथ चुना था। उदा.
SELECT
,C.value('CVElementId[1]', 'INT') AS [CVElementId]
,C.value('../SequenceNumber[1]', 'INT') AS [Level]
FROM
[dbo].[XmlFiles]
CROSS APPLY
[Data].nodes('/CVSet/Level/CVElement') AS T(C)
पाया गया कि इसे संभालने का सबसे अच्छा तरीका एक्सएमएल पर "बाहरी जुड़ाव" करने के लिए OUTER APPLY का उपयोग करना था।
SELECT
,C.value('CVElementId[1]', 'INT') AS [CVElementId]
,B.value('SequenceNumber[1]', 'INT') AS [Level]
FROM
[dbo].[XmlFiles]
CROSS APPLY
[Data].nodes('/CVSet/Level') AS T(B)
OUTER APPLY
B.nodes ('CVElement') AS S(C)
आशा है कि यह किसी की मदद करता है क्योंकि यह मेरा दिन काफी अच्छा रहा है।