SQL将字符串字段转换为XML慢

问题描述

我在MS sql中有一个表,其中的字段包含一个表示XML的字符串,如下所示:

        < Root >
           < Value_Tab2 ID = "182" >    
               < Value_Tab3 >
                   < Value > 1219 </ Value > 
              </ Value_Tab3 >
           </ Value_Tab2 >
           < Value_Tab2 ID = "187" >
               < Value_Tab3 >
                   < Value > 3192 </ Value >
               </ Value_Tab3 >
           </ Value_Tab2 >
        </ Root >

我可以将此字段转换字符串查询为XML,但是对于MyTable1的50000行,查询需要7到8秒的时间。我使用的查询是这样的:

        SELECT MT1.ID,cast(MT1.StringXml as xml).value('(Root/Value_Tab2/@ID)[1]','INT') AS MT1_ID1,cast(MT1.StringXml as xml).value('(Root/Value_Tab2/@ID)[2]','INT') AS MT1_ID2,cast(MT1.StringXml as xml).value('(Root/Value_Tab2/Value_Tab3/Value)[1]','INT') AS VALUE_ID1,cast(MT1.StringXml as xml).value('(Root/Value_Tab2/Value_Tab3/Value)[2]','INT') AS VALUE_ID2
        FROM MyTable1 MT1 with (NOLOCK)
        WHERE MT1.Published = 1 

StringXML是MyTable1,归档为nvarchar(MAX);这是查询字符串字段并转换为XML的正确方法吗?

还有什么其他方法解决方法可以提高查询性能

解决方法

您需要做的就是XML粉碎。

请尝试以下操作。

正如@PanagiotisKanavos指出的那样,CAST操作仅执行一次。所有XPath表达式都针对性能进行了优化。

SQL

-- DDL and sample data population,start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY,Published BIT,StringXml NVARCHAR(MAX));
INSERT INTO @tbl (Published,StringXml) VALUES
(1,N'<Root>
    <Value_Tab2 ID="182">
        <Value_Tab3>
            <Value>1219</Value>
        </Value_Tab3>
    </Value_Tab2>
    <Value_Tab2 ID="187">
        <Value_Tab3>
            <Value>3192</Value>
        </Value_Tab3>
    </Value_Tab2>
</Root>');
-- DDL and sample data population,end

;WITH rs AS
(
    SELECT ID,Published,TRY_CAST(StringXml AS XML) AS xmldata
    FROM @tbl
)
SELECT ID,c.value('Value_Tab2[1]/@ID','INT') AS MT1_ID1,c.value('Value_Tab2[2]/@ID','INT') AS MT1_ID2,c.value('(Value_Tab2[1]/Value_Tab3/Value/text())[1]','INT') AS VALUE_ID1,c.value('(Value_Tab2[2]/Value_Tab3/Value/text())[1]','INT') AS VALUE_ID2
FROM rs
    CROSS APPLY xmldata.nodes('/Root') AS t(c)
WHERE rs.Published = 1;

输出

+----+---------+---------+-----------+-----------+
| ID | MT1_ID1 | MT1_ID2 | VALUE_ID1 | VALUE_ID2 |
+----+---------+---------+-----------+-----------+
|  1 |     182 |     187 |      1219 |      3192 |
+----+---------+---------+-----------+-----------+