Ben*_*ack 5 sql-server performance ssms
我处于常年的情况:一个查询通过一些读取立即通过SSMS运行,但在通过ADO.NET运行时足够慢以及数千个读取超时. 与我在StackOverflow上可以找到的其他问题不同,清除查询缓存(或强迫自己使用SSMS使用的那个)似乎没有做到这一点.
通常,当其他人在StackOverflow上报告这种情况时,他们已经有了损坏的查询缓存.在所有这些情况下,修复程序要么运行ADO.NET查询SET ARITHABORT ON(以匹配SSMS使用的会话设置),要么运行DBCC DROPCLEANBUFFERS并DBCC FREEPROCCACHE强制查询缓存重建.这些技术在我的应用程序中没有任何区别,让我相信有更基本的东西在继续.
有问题的查询是这样的(SQL Profiler捕获的实际逐字查询,仅为格式化而清理):
declare @p5 xml
set @p5=convert(xml,N'<r>
<n v="66ebc21b3bcb31e9a5ecbfb4b29fd2a47c37994c"/>
<n v="665919306fb23d9e685638a2d199e1e623745305"/>
<n v="a080c3b4e0c86e37b4d494d5efc09cebe20c6929"/>
<n v="245cb49bdeca9e37ef9bbd55877e21ade14e6282"/>
<n v="297650a6be65be332c1bb2aab426331a156ee342"/>
<n v="6a2668c8ab64fecf3b6925c7be613c61cef4dd7c"/>
<n v="09923f25f8b1de19f693bca1111bfa50d617856e"/>
<n v="0a7836d8e4e34f4ea92b2105eea5a99029949428"/></r>')
exec sp_executesql N'
SELECT ixChangesetTag, ixRepo, ixChangeset, sTag, fBookmark
FROM ChangesetTag
INNER JOIN @p2.nodes(''/r/n'') X(n) ON X.n.value(''xs:hexBinary(@v)'', ''binary(20)'') = ixChangeset
WHERE ixRepo = @p0 AND ixCustomer = @p1',N'@p0 bigint,@p1 int,@p2 xml',@p0=2,@p1=23363,@p2=@p5
Run Code Online (Sandbox Code Playgroud)
(XML参数是为了允许使用参数化查询,我通常会遇到这样的问题,因为我想传入的对象数量各不相同.表值程序将是2008年的方法,但有些我们的客户在2005年运行.)
通过SSMS运行,所使用的实际查询计划看起来合适(索引搜索),并且在4ms内进行大约200次读取.通过Web应用程序运行,一秒钟内需要大约4500次读取.
我在这里错过了什么?可以通过Web应用程序恢复错误的查询计划,尽管有DBCC调用和ARITHABORT设置?
问题最终是 SQL Server 通常选择了一种绝对糟糕的执行策略,基本上是重复循环 XML,而不是执行正常的连接。修复方法是将 XML 放入临时表中并连接该表,这可靠地产生了良好的执行计划。