MSSQL XML 性能问题
MSSQL XML Performance Issue
示例数据:
<Data>
<row preis="2.4000" anzahl="72.0000" rabatt="0.0000" mwst="16.0000" bez="tägliche Standreinigung" adoku_nr="1694351" adr_nr="95" anmpos_nr="-1" doku_nr="1694351" gen="0" pos="12" preis_vk="2.4000" preis_lp="2.4000" druck="1" artikel_nr="601" artposarten_nr="1" />
<row preis="330.0000" anzahl="1.0000" rabatt="0.0000" mwst="15.0000" bez="Abwasseranschluß" adoku_nr="500570" adr_nr="95" anmpos_nr="1" doku_nr="500570" gen="0" pos="6" preis_vk="330.0000" preis_lp="330.0000" druck="1" artikel_nr="304" artposarten_nr="1" />
</Data>
我的目标是为 adoku_nr(行的 ID)、属性名称、属性值设置列。
我通过
实现了这个
select
T.C.value('(../@adoku_nr)[1]', 'int') as ID,
T.C.value('local-name(.)', 'nvarchar(128)') as Name,
T.C.value('(.)[1]', 'nvarchar(max)') as Value
from @Data.nodes('/Data/row/@*') as T(C)
结果:
ID Name Value
1694351 preis 2.4000
1694351 anzahl 72.0000
1694351 rabatt 0.0000
1694351 mwst 16.0000
1694351 bez tägliche Standreinigung
1694351 adoku_nr 1694351
1694351 adr_nr 95
1694351 anmpos_nr -1
1694351 doku_nr 1694351
1694351 gen 0
1694351 pos 12
1694351 preis_vk 2.4000
1694351 preis_lp 2.4000
1694351 druck 1
1694351 artikel_nr 601
1694351 artposarten_nr 1
500570 preis 330.0000
500570 anzahl 1.0000
500570 rabatt 0.0000
500570 mwst 15.0000
500570 bez Abwasseranschluß
500570 adoku_nr 500570
500570 adr_nr 95
500570 anmpos_nr 1
500570 doku_nr 500570
500570 gen 0
500570 pos 6
500570 preis_vk 330.0000
500570 preis_lp 330.0000
500570 druck 1
500570 artikel_nr 304
500570 artposarten_nr 1
现在我的问题是,如果我在更大的 xml 上执行此查询,在我的例子中有 120 行,它变得非常慢(4 秒),问题似乎是 ID 列,没有它我回到较低的毫秒括号。
有没有办法优化此查询以实现相同的目标但性能更好?
您可以将此需求作为 XQuery
纳入您的 XPath
看看[@adoku_nr=sql:variable("@rowId")]
declare @data XML=
'<Data>
<row preis="2.4000" anzahl="72.0000" rabatt="0.0000" mwst="16.0000" bez="tägliche Standreinigung" adoku_nr="1694351" adr_nr="95" anmpos_nr="-1" doku_nr="1694351" gen="0" pos="12" preis_vk="2.4000" preis_lp="2.4000" druck="1" artikel_nr="601" artposarten_nr="1" />
<row preis="999" anzahl="999" rabatt="9999" mwst="16.0000" bez="tägliche Standreinigung" adoku_nr="999" adr_nr="95" anmpos_nr="-1" doku_nr="1694351" gen="0" pos="12" preis_vk="2.4000" preis_lp="2.4000" druck="1" artikel_nr="601" artposarten_nr="1" />
</Data>';
declare @rowId varchar(100)='1694351'; --try with "999" here to get the other row
select
T.C.value('(../@adoku_nr)[1]', 'int') as ID,
T.C.value('local-name(.)', 'nvarchar(128)') as Name,
T.C.value('(.)[1]', 'nvarchar(max)') as Value
from @Data.nodes('/Data/row[@adoku_nr=sql:variable("@rowId")]/@*') as T(C)
来自我的魔法玻璃灯泡的更新
行上有 .nodes()
,属性上有 CROSS APPLY r.nodes()
,您将直接向下走。不需要昂贵的向后导航...
我假设您正在寻找这个:
select
r.value('@adoku_nr', 'int') as ID,
a.value('local-name(.)', 'nvarchar(128)') as Name,
a.value('.', 'nvarchar(max)') as Value
from @Data.nodes('/Data/row') as A(r)
cross apply r.nodes('@*') AS B(a)
示例数据:
<Data>
<row preis="2.4000" anzahl="72.0000" rabatt="0.0000" mwst="16.0000" bez="tägliche Standreinigung" adoku_nr="1694351" adr_nr="95" anmpos_nr="-1" doku_nr="1694351" gen="0" pos="12" preis_vk="2.4000" preis_lp="2.4000" druck="1" artikel_nr="601" artposarten_nr="1" />
<row preis="330.0000" anzahl="1.0000" rabatt="0.0000" mwst="15.0000" bez="Abwasseranschluß" adoku_nr="500570" adr_nr="95" anmpos_nr="1" doku_nr="500570" gen="0" pos="6" preis_vk="330.0000" preis_lp="330.0000" druck="1" artikel_nr="304" artposarten_nr="1" />
</Data>
我的目标是为 adoku_nr(行的 ID)、属性名称、属性值设置列。
我通过
实现了这个select
T.C.value('(../@adoku_nr)[1]', 'int') as ID,
T.C.value('local-name(.)', 'nvarchar(128)') as Name,
T.C.value('(.)[1]', 'nvarchar(max)') as Value
from @Data.nodes('/Data/row/@*') as T(C)
结果:
ID Name Value
1694351 preis 2.4000
1694351 anzahl 72.0000
1694351 rabatt 0.0000
1694351 mwst 16.0000
1694351 bez tägliche Standreinigung
1694351 adoku_nr 1694351
1694351 adr_nr 95
1694351 anmpos_nr -1
1694351 doku_nr 1694351
1694351 gen 0
1694351 pos 12
1694351 preis_vk 2.4000
1694351 preis_lp 2.4000
1694351 druck 1
1694351 artikel_nr 601
1694351 artposarten_nr 1
500570 preis 330.0000
500570 anzahl 1.0000
500570 rabatt 0.0000
500570 mwst 15.0000
500570 bez Abwasseranschluß
500570 adoku_nr 500570
500570 adr_nr 95
500570 anmpos_nr 1
500570 doku_nr 500570
500570 gen 0
500570 pos 6
500570 preis_vk 330.0000
500570 preis_lp 330.0000
500570 druck 1
500570 artikel_nr 304
500570 artposarten_nr 1
现在我的问题是,如果我在更大的 xml 上执行此查询,在我的例子中有 120 行,它变得非常慢(4 秒),问题似乎是 ID 列,没有它我回到较低的毫秒括号。 有没有办法优化此查询以实现相同的目标但性能更好?
您可以将此需求作为 XQuery
纳入您的 XPath
看看[@adoku_nr=sql:variable("@rowId")]
declare @data XML=
'<Data>
<row preis="2.4000" anzahl="72.0000" rabatt="0.0000" mwst="16.0000" bez="tägliche Standreinigung" adoku_nr="1694351" adr_nr="95" anmpos_nr="-1" doku_nr="1694351" gen="0" pos="12" preis_vk="2.4000" preis_lp="2.4000" druck="1" artikel_nr="601" artposarten_nr="1" />
<row preis="999" anzahl="999" rabatt="9999" mwst="16.0000" bez="tägliche Standreinigung" adoku_nr="999" adr_nr="95" anmpos_nr="-1" doku_nr="1694351" gen="0" pos="12" preis_vk="2.4000" preis_lp="2.4000" druck="1" artikel_nr="601" artposarten_nr="1" />
</Data>';
declare @rowId varchar(100)='1694351'; --try with "999" here to get the other row
select
T.C.value('(../@adoku_nr)[1]', 'int') as ID,
T.C.value('local-name(.)', 'nvarchar(128)') as Name,
T.C.value('(.)[1]', 'nvarchar(max)') as Value
from @Data.nodes('/Data/row[@adoku_nr=sql:variable("@rowId")]/@*') as T(C)
来自我的魔法玻璃灯泡的更新
行上有 .nodes()
,属性上有 CROSS APPLY r.nodes()
,您将直接向下走。不需要昂贵的向后导航...
我假设您正在寻找这个:
select
r.value('@adoku_nr', 'int') as ID,
a.value('local-name(.)', 'nvarchar(128)') as Name,
a.value('.', 'nvarchar(max)') as Value
from @Data.nodes('/Data/row') as A(r)
cross apply r.nodes('@*') AS B(a)