我有一个包含大量大型 xml 文档的表格。
当我运行 xpath 表达式从这些文档中选择数据时,我遇到了一个特殊的性能问题。
我的查询是
SELECT
p.n.value('.', 'int') AS PurchaseOrderID
,x.ProductID
FROM XmlLoadData x
CROSS APPLY x.PayLoad.nodes('declare namespace NS="http://schemas.datacontract.org/2004/07/XmlDbPerfTest";
/NS:ProductAndRelated[1]/NS:Product[1]/NS:PurchaseOrderDetails[1]/NS:PurchaseOrderDetail/NS:PurchaseOrderID[1]') p(n)
Run Code Online (Sandbox Code Playgroud)
查询需要 2 分 8 秒。
当我[1]
像这样删除单个出现节点的部分时:
SELECT
p.n.value('.', 'int') AS PurchaseOrderID
,x.ProductID
FROM XmlLoadData x
CROSS APPLY x.PayLoad.nodes('declare namespace NS="http://schemas.datacontract.org/2004/07/XmlDbPerfTest";
/NS:ProductAndRelated/NS:Product/NS:PurchaseOrderDetails/NS:PurchaseOrderDetail/NS:PurchaseOrderID') p(n)
Run Code Online (Sandbox Code Playgroud)
执行时间降至仅 18 秒。
由于[1]
-nodes 在文档中的每个父节点中只出现一次,因此除了排序之外结果是相同的。
第一个(慢)查询的实际执行计划是
第二个(更快的)查询是
据我所见,有查询[1]
的执行与没有查询的执行相同,但增加了一些额外的计算步骤来查找第一项。
我的问题是为什么第二个查询更快。
我原以为查询的执行会在[1]
找到匹配项时提前中断,从而减少执行时间而不是相反。
是否有任何原因导致执行不会提前中断[1]
,从而减少执行时间。
这是我的桌子
CREATE TABLE [dbo].[XmlLoadData](
[ProductID] [int] NOT …
Run Code Online (Sandbox Code Playgroud)