对具有索引的查询,数据库读取变化很大

时间:2010-09-09 12:29:35

标签: sql-server database performance sql-server-2008 sql-server-2008-r2

我的查询具有适当的索引,并显示在查询计划中,估计的子树成本约为1.5。该计划显示了一个Index Seup,然后是Key Lookup - 这对于一个预期从5到20行之间返回1行的查询来说很好(即Index Seek应该找到5到20行之间,以及5到20之后)关键查找,我们应该返回1行)。

以交互方式运行时,查询几乎立即返回。但是,今天早上的数据库跟踪显示了来自live(一个Web应用程序)的运行时间变化很大;通常查询正在< 100 DB读取,有效地运行0 ...但我们正在进行一些消耗> 170,000 DB读取,运行时间最长60s(大于我们的超时值)。

什么可以解释磁盘读取的这种变化?我尝试以交互方式比较查询,并使用来自两个并行运行的实际执行计划,其中过滤值来自快速和慢速运行,但是交互式地显示了所使用的计划没有区别。

我还尝试识别可以锁定此查询的其他查询,但我不确定这会对数据库读取产生如此大的影响......并且无论如何这个查询在跟踪日志中往往是运行时最差的

更新:以下是以交互方式运行查询时生成的计划示例:

alt text

忽略“缺失索引”文字。 是真的,对当前索引的更改可以允许更快的查询和更少的查找,但这不是问题(已经有适当的索引)。这是实际执行计划,我们在其中看到实际行数等数字。例如,在Index Seek上,实际行数为16,I / O成本为0.003。密钥查找的I / O成本相同。

更新2:此查询的跟踪结果为:

exec sp_executesql N'select [...column list removed...] from ApplicationStatus where ApplicationGUID = @ApplicationGUID and ApplicationStatusCode = @ApplicationStatusCode;',N'@ApplicationGUID uniqueidentifier,@ApplicationStatusCode bigint',@ApplicationGUID='ECEC33BC-3984-4DA4-A445-C43639BF7853',@ApplicationStatusCode=10

使用Gentle.Framework SqlBuilder类构建查询,该类构建参数化查询,如下所示:

SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof(ApplicationStatus));
sb.AddConstraint(Operator.Equals, "ApplicationGUID", guid);
sb.AddConstraint(Operator.Equals, "ApplicationStatusCode", 10);
SqlStatement stmt = sb.GetStatement(true);
IList apps = ObjectFactory.GetCollection(typeof(ApplicationStatus), stmt.Execute());

2 个答案:

答案 0 :(得分:1)

是否可以从缓存中删除数据?这可能是一个解释为什么使用热缓存(数据已经在内存中),记录的读取非常低......然后当数据不再在RAM中时,读取会增加,因为它必须从磁盘读取它试。

只有一个想法让事情发生变化。

答案 1 :(得分:1)

运行探查器以查看统计信息是否在同一时间更新。或者只是看看还有什么。

另外,请添加SQL查询以及客户端代码。

思想:

  • 听起来你的“5-20”行可能远远超过
  • 糟糕的计划/参数嗅探你会得到一贯糟糕的表现
  • 如何在此表上发生写入:足以更新统计信息?
  • 是否存在某些数据类型问题? (例如,连接参数并引入数据类型转换)