SQL Server 优化---为何索引视图(物化视图)须要with(noexpand)强制查询提示

原文: SQL Server 优化---为何索引视图(物化视图)须要with(noexpand)强制查询提示

 

本文出处:http://www.cnblogs.com/wy123/p/6694933.html html

 

第一次经过索引视图优化SQL语句,以及遇到的一些问题,记录一下。sql

 

语句分析数据库

最近开发递交过来一个查询统计的SQL,说是性能有问题,本来执行须要4-5秒钟,这个业务自己对性能要求又比较critical,指望是在1s以内
在用尽各类办法以后(执行计划,统计信息,索引,改写SQL,临时表拆分),依然没有实质性的改观,
在观察SQL自己的特色以后,
有如下几个特色
  1,查询语句总体为多表join,可是每一个表自身的数据并非很是大,百万级
  2,查询结果在主表上一个较大的时间范围的数据进行Count的聚合操做
  3,几张表之间除了链接条件,主要是进行了一些比较复杂的逻辑运算(下面截图能够看到,没多少IO,CPU时间却很高)
    不过表的链接方式都是inner join,主要性能点就在于表关联之间的Hash join之间的逻辑运算,参考下图(是执行计划的一部分)sqlserver

  经过统计信息发现,该SQL语句的物理IO并不高,说明索引没有什么问题,经过索引改善IO可能改善空间颇有限
  时间主要花费在SQL语句的编译和的Hash join 运算
  尝试改写借助SQL以后(纯改写SQL和借助临时表拆分语句),发现依然很难绕过Hash join,主要是表之间的逻辑运算最为耗时
  最后想到能够先将运算好的的数据物理存储起来,而后改写查询的SQL语句完成等价的查询,
  避免每次查询都作复杂的逻辑运算,应该能够有比较大的改善,因而就想到了索引视图性能

  

建立索引视图改写SQL优化

  在提取出来原始的查询SQL,建立索引视图,并在索引视图上建立unique cluster index和合理的nocluster index
  经过索引视图改写原始的查询统计SQL语句,
  改写后的SQL语句是一个索引视图替代原始的4张表,与另一个物理表join,发现效率上没有任何改善,
  观察改写后的SQL语句的执行计划,发现跟原始SQL同样,并无走索引视图上的索引,或者说是用到索引视图,一时间以为好心塞,实在没招了
  执行计划依旧是长长的一大段,而后依旧是好几个Hash Join.参考下图,执行计划跟本文第一个截图如出一辙google

  按道理,索引视图固化结果集,而且根据状况作了过滤,结果集是原始查询的一部分而已,
  用一样的查询条件从索引视图作查询统计,走索引视图代价确定要比原始SQL低,经过强制不展开with(noexpand)提示,证明了这个推断
  以下是强制不展开索引视图的统计信息,能够看到彻底达到了预期的1S以内3d

  

 

  固然索引视图也不是没有代价,在必定程度上牺牲了数据写入的效率和冗余存储,来换取查询的效率
  以前简单介绍过索引视图的一些特色 http://www.cnblogs.com/wy123/p/6041122.htmlserver

 

索引视图被展开(expand)的缘由分析htm

  最关键的问题在于,没有强制不展开索引视图(with(noexpand)提示)的状况下,为何没有走索引视图呢?

  这个问题确实郁闷了一阵子,整个半天都在想这个问题,由于索引视图自己用的就少,出现此问题更是一头雾水,不过Google一下,还有一大把相似的问题
  以下是在google的时候查到的,原文是英文,大概意思以下,非直译。

  参考连接:http://dba.stackexchange.com/questions/26979/what-factors-go-into-an-indexed-views-clustered-index-being-selected/27039#27039

索引视图的匹配(查询用索引视图替代而不走原始的基础表)是一个至关昂贵的操做,所以优化器试图经过其余方式快速转换(生成执行计划)
若是优化器产生了一个相对优化的执行计划,就能够尽早结束(没必要继续生成其余执行计划)
问题就在于:继续生成其余执行计划的代价要大于已生成的执行计划的代价
听起来有点别扭,
以前举过这么一个例子,好比说是花3秒钟找到一个相对优化的执行计划,这个执行计划完成SQL的执行须要2秒钟
与花10秒钟的时候找到一个最优化的执行计划,尽管这个执行计划完成SQL的执行可能只须要0.5秒钟,虽而后者的执行计划更优,但总体代价更大
优化器的主要目标是尽快找到一个足够好的执行计划(而非老是生成最好的执行计划)

使用索引视图自己并非一个昂贵的操做,
可是与潜在索引视图中匹配逻辑查询树确实一个代价较大的行为,在查询涉及的视图在优化器优化以前已经被展开
所以优化器并不知道你的查询是否未被了索引视图,他看到的只是展开的查询树
这个通俗地讲就是:
让sqlserver知道,一个查询,能够用索引视图中的结果等价替代视图逻辑中原始的基表,是一个代价较大的过程
由于SQL Server根据原始的基础表,生成一种执行计划以后,就不去判断是否能够用索引视图作等价替代。

   固然白皮书里有更详细的介绍,里面索引视图相关的一些逻辑实现和分析http://www.cs.cmu.edu/~natassa/courses/15-823/current/papers/vldb00.pdf

 

最后多逼逼一句:
  上面的白皮书实在看不懂,只是Google出来讲详细信息请看这个参考资料,
  这里只是从现象去推断优化器在面对索引视图的一些特性,了解到内在机制的一些特色,可能潜在的问题,以及对应的解决办法
  这里又提开源软件了,别说不开源了,即使是开源了,除了钱的因素,在技术上,有几我的能够动一下这些大型软件的核心代码?
  我并非在黑开源软件啊,只是听有人说,开源好啊,有源码怎么怎么样,以为够装13的,
  国内除了bat等少数几家公司作过修改源码,作过开源数据库的定制,试问还有多少家能够修改数据库源码而后上生产使用

  最近在学MySQL,继续SQL Server下去恐怕踏马要失业了,开源,对大多数公司来讲,钱才是一个大头因素吧,尼玛跑题了。

相关文章
相关标签/搜索