使用索引统计信息优化查询语句,提高查询效率
作者:网络转载 发布时间:[ 2013/4/8 10:37:17 ] 推荐标签:
了解上面的基础知识,那么开始本文的重点,实际操作中怎么Using Statistics to Improve Query Performance通常情况下,设置了 AUTO_CREATE_STATISTICS 和AUTO_UPDATE_STATISTICS的话,数据库会自动去创建管理了,但是有时候并不尽人意。尤其是它创建了统计信息,但是更新的不及时,导致查询执行时间很长。这类情况明显的一个特征是你修改where条件的参数值,执行时间会有非常大的差异。例如下面这个例子
--1
SELECT COUNT(*)
FROM a WITH (NOLOCK) ,
b WITH (NOLOCK)
WHERE a.Daytime = b.AccountDate
AND a.Siteid = b.Siteid
AND a.Prodid = b.Prodid
AND b.Daytime = '2013-2-28'
--2
SELECT COUNT(*)
FROM a WITH (NOLOCK) ,
b WITH (NOLOCK)
WHERE a.Daytime = b.AccountDate
AND a.Siteid = b.Siteid
AND a.Prodid = b.Prodid
AND b.Daytime = '2013-3-31'
两个表a ,b的数据量都在五六百万左右,结构上b表是联合主键(Daytime,Prodid,Siteid),a表中这三个列是非聚集联合索引。这是一个比较简单的内连接语句,当更改日期参数,前者只需要1s,后者需要30+;
为什么会出现这样的差异呢,这里说下我的分析思路,先看执行计划差异很大(这里我不贴图了)。主要差异是第一个走了哈希联接,第二个是LOOP JOIN(LOOP JOIN和哈希联接的具体信息可以参考联机帮助上的说明),这两个表的数据量都比较大,所以LOOP JOIN是不合理的方案。按照正常来说执行计划应该是一样的,我首先想到的是索引碎片,通过脚本查看两个被使用到的索引碎片率很低,排除掉这个原因,然后想到了索引统计信息,发现a表主键上一次更新统计信息的日期是在2013-03-04 ,然后调整日期参数,这个之前的查询都很快,后面的都特慢。然后使用 UPDATE STATISTICS更新了统计信息,两个语句的执行计划都一致了,速度都正常了。
总结:对于改天查询中的一个参数或多个参数值导致查询执行时间差异很大的语句,多半是Statistics没有及时跟上,我们需要手动更新一下。在之后我们观察这个索引的自动更新统计是否为ON,如果配置正常但是Statistics还不能及时跟上的建议建立一个job定期检查统计信息更新情况并处理。

sales@spasvo.com