Alb*_*nbo 7 performance sql-server-2008
我有一个包含大量大型 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 NULL,
[PayLoad] [xml] NOT NULL,
[Size] AS (len(CONVERT([nvarchar](max),[PayLoad],0))),
CONSTRAINT [PK_XmlLoadData] PRIMARY KEY CLUSTERED
(
[ProductID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
编辑:
来自 SQL Profiler 的性能数据:
查询 1:
CPU Reads Writes Duration
126251 1224892 0 129797
Run Code Online (Sandbox Code Playgroud)
查询 2:
CPU Reads Writes Duration
50124 612499 0 16307
Run Code Online (Sandbox Code Playgroud)
第二个查询使用并行性。也就是说,它的成本足以让优化器对额外的开销视而不见。
我猜第二个查询告诉优化器“转储所有内容”,这是通过并行扫描执行的。SQL Server 喜欢在被要求时以这种方式“转储所有内容”。
而第一个查询要求“分析然后给出一些”。无论如何,优化器无法知道只有一个节点,因此它最终选择的执行计划非常不同。
我想说这类似于一次表扫描比多次索引查找便宜的情况。
归档时间: |
|
查看次数: |
3288 次 |
最近记录: |