【发布时间】:2016-06-02 04:12:50
【问题描述】:
我在 XML 数据类型上的 ORDER BY 操作非常缓慢。请忽略示例中的 XML 是扁平的,可以存储在表中的事实,这是测试数据。
我有一个 SQL Server 表 (ID int primary identity, body XML),并且主体上有主要和次要 XML PATH 索引。
我的正文中的 XML 如下所示:
<Doc SerialNumber="000000000000000001122222" Mfg="0" Model="DXBYCD1" AcDate="5/29/2015 9:49:27 AM" />
我的查询
SELECT TOP 10
a.ID, a.Tag, a.GD, a.Body,
a.body.value('(Doc/@SerialNumber)[1]', 'nvarchar(50)') AS Serial,
a.body.value('(Doc/@Model)[1]', 'nvarchar(50)') AS Model
FROM
Asset a
ORDER BY
Model
完成表中的 500 万条记录大约需要 45 秒。
索引正在工作,因为如果我添加带有body.exist(...) 的 WHERE 子句,结果几乎是即时的(2 毫秒)。
我花了很长时间寻找改进 XML 索引以实现快速ORDER BY 的方法。有什么帮助吗?
编辑: 看起来不同之处在于 WHERE 正在使用索引。
当我使用这个子句时:
where a.body.value('(Doc/@SerialNumber)[1]', 'nvarchar(50)') = '000000000000000000000002'
大约需要 90 秒。但是,当我使用这个子句时:
where body.exist('/Doc/@SerialNumber[. = "000000000000000000000002"]') = 1
它立即完成。
所以,如果比较发生在 xquery 内部,我可以看到 SQL 在哪里更好地利用索引。在我原来的情况下,ORDER BY 发生在值语句上,优化器没有利用。
我更新的问题...有没有办法在 xpath 查询中使用order by 来排序结束结果列表?
【问题讨论】:
-
你能添加一个计算列来计算模型和索引吗?
-
您的编辑显示完全相同,正如我在答案中的链接问题中发现的那样。 XML 索引将加速查询,您可以在其中使用完整路径,从 single 斜杠开始,一直到整行...没有
*或[...]或任何其他内容。其他查询的性能甚至比没有索引的情况还要糟糕……你读过吗?这是值得的...... -
@MartinSmith 是的,这是一个选项,并且绝对可以更轻松地报告,但会增加插入时间、数据库大小等。我们目前有一个性能非常好的 EAV 实现,它可能比生成计算列更受欢迎对于我们可以排序或过滤的所有内容(我们从 EAV 生成广泛的视图)
-
@lawrence,如果数据库大小和插入性能很重要,您应该更多地考虑您的 XML 索引 ...
-
@Shnugo 是的,我看到了链接,并希望找到有关 orderby 执行的更多具体信息。 XML 的 db 大小实际上比 EAV 更好,但几乎没有(主/外键/空列更少)。如果我找不到对 xml 的更多控制,可能需要保留 EAV 模式
标签: sql sql-server xml performance indexing