我的XML结构:
<Items>
<Item>
<guid>FC550573-7171-997F-752D-8D65590CBFD6</guid>
<Objects>
<Object>
<type>0</type>
<guid>E10D9DA9-2C8D-8024-2F07-DF21395811BF</guid>
</Object>
<Object>
<type>0</type>
<guid>D8338400-35C7-781E-A039-C0FDDF80714A</guid>
</Object>
</Objects>
</Item>
</Items>
填写对象表时:
CREATE TABLE [dbo].[Objects](
[item_guid] [varchar](36) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[type] [int] NOT NULL,
[guid] [varchar](36) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
) ON [PRIMARY]
使用查询:
INSERT INTO [dbname].[dbo].[Objects]
([item_guid]
,[type]
,[guid])
SELECT
X.source.query('../../guid').value('.','VARCHAR(36)') as item_guid,
X.source.query('type').value('.','INT') as type,
X.source.query('guid').value('.','VARCHAR(36)') as guid
FROM(
Select xmldata from XmlFiles where fullpath=@fp
) AS T(x)
CROSS APPLY x.nodes('Items/Item/Objects/Object') As X(source)
此行使查询非常缓慢:
X.source.query('../../guid').value('.','VARCHAR(36)') as item_guid
这里适当的方法是什么?
答案 0 :(得分:7)
使用/text()
获取值有助于提高无类型XML的性能。使用父轴../..
也是不好的(如@marc_s建议的那样)。
这是一个带有额外交叉申请和/text()
的版本来获取值。
试试这个:
select T2.N.value('(guid/text())[1]', 'uniqueidentifier') as item_guid,
T3.N.value('(type/text())[1]', 'int') as type,
T3.N.value('(guid/text())[1]', 'uniqueidentifier') as guid
from (SELECT xmldata FROM dbo.XmlFiles WHERE fullpath = @fp) as T1(N)
cross apply T1.N.nodes('Items/Item') as T2(N)
cross apply T2.N.nodes('Objects/Object') as T3(N)
您必须判断哪个查询对您来说最快。
答案 1 :(得分:2)
我只是想补充一下,如果其他人遇到这种情况,添加以下选项会产生巨大的差异。
OPTION (OPTIMIZE FOR (@testXml = NULL))
如果您想自己测试一下,这里有一个我正在运行的简短测试脚本。只需看看这些之间的估计子树成本。
declare @testXml xml set @testXml = '<filters><filter name="test name" type="GREATERTHAN">1</filter><filter name="CLAIMID" type="GREATERTHAN">1</filter></filters>'
select x.value('@name','nvarchar(100) ') filtername,
x.value('.','nvarchar(200)')filtervalue,
x.value('@type','nvarchar(50) ') filtertype
from @testXml.nodes('/filters/filter') as ref(x)
--vs...
select x.value('@name','nvarchar(100) ') filtername,
x.value('.','nvarchar(200)')filtervalue,
x.value('@type','nvarchar(50) ') filtertype
from @testXml.nodes('/filters/filter') as ref(x)
OPTION (OPTIMIZE FOR (@testXml = NULL))
答案 2 :(得分:1)
试试这个,
我们将创建一个临时表变量来存储此xml值&amp;插入相应的表对象
//..Xml value to temp variable
Declare @x xml ='<Items><Item><guid>FC550573-7171-997F-752D-8D65590CBFD6</guid><Objects><Object>
<type>0</type><guid>E10D9DA9-2C8D-8024-2F07-DF21395811BF</guid></Object><Object>
<type>0</type><guid>D8338400-35C7-781E-A039-C0FDDF80714A</guid></Object></Objects>
</Item></Items>';
Declare @Temp_Tbl table (RowId int identity, item_guid nvarchar(36), [type] int, [guid] nvarchar(36));
Insert into @Temp_Tbl SELECT @x.value('(/Items/Item/guid)[1]', 'nvarchar(36)'),
Cont.value('(type)[1]', 'int'), Cont.value('(guid)[1]', 'nvarchar(36)')
FROM @x.nodes('/Items/Item/Objects/Object') AS Obj(Cont);
INSERT INTO [dbo].[Objects] Select item_guid,[type],[guid] from @Temp_Tbl;