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

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

语句分析

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

  通过统计信息发现,该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.参考下图,执行计划跟本文第一个截图一模一样

  按道理,索引视图固化结果集,并且根据情况做了过滤,结果集是原始查询的一部分而已,   用同样的查询条件从索引视图做查询统计,走索引视图代价肯定要比原始SQL低,通过强制不展开with(noexpand)提示,证实了这个推断   如下是强制不展开索引视图的统计信息,可以看到完全达到了预期的1S之内

  

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

索引视图被展开(expand)的原因分析

  最关键的问题在于,没有强制不展开索引视图(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出来说详细信息请看这个参考资料,   这里只是从现象去推断优化器在面对索引视图的一些特性,了解到内在机制的一些特点,可能潜在的问题,以及对应的解决办法

SQL Server 优化---为什么索引视图(物化视图)需要with(noexpand)强制查询提示相关推荐

  1. CREATE VIEW SQL:在SQL Server中使用索引视图

    This is the fourth article in a series of learning the CREATE VIEW SQL statement. So far, we have do ...

  2. oracle access advisor,使用Oracle SQL Access Advisor改善数据库索引与物化视图

    当针对表集增加物化视图(materialized view)和索引时,理论上这些表的查询性能会得到改善.但事实上并不一定能达到理想的状态,因此Oracle推出了SQL Access Advisor工具 ...

  3. SQL Server 2000 ——系统表和系统视图

    一.系统表 数据字典的详细信息请查SQL SERVER BOL,这里仅列出一部分. 1.1.sysservers 1.查看所有本地服务器及链接服务器 select * from master..sys ...

  4. oracle物化视图可以创建索引,oracle 物化视图及创建索引

    物化视图是一种特殊的物理表,"物化"(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,Oracle都实际上转换为视图SQL语 ...

  5. 【数据操作】优化SQL server性能 之 索引 (转上)

    数据库的逻辑设计.包括表与表之间的关系是优化关系型数据库性能的核心.一个好的逻辑数据库设计可以为优化数据库和应用程序打下良好的基础. 数据库的逻辑设计.包括表与表之间的关系是优化关系型数据库性能的核心 ...

  6. sql server(MsSql)字段命名,表命名,视图命名,SQL语句书写参考

    @[TOC](sql server(MsSql)字段命名,表命名,视图命名,SQL语句书写参考) 对我个人来说,字段命名,表命名,视图命名,SQL语句书写都有一套自己的习惯,可以减少维护成本.减少不必 ...

  7. [SQL Server优化]善用系统监视器,确定系统瓶颈

    原文: [SQL Server优化]善用系统监视器,确定系统瓶颈 来自: http://hi.baidu.com/solorez/blog/item/f82038fa0e71b78d9e51468c. ...

  8. sql优化基数和耗费_基数估计在SQL Server优化过程中的位置

    sql优化基数和耗费 In this blog post, I'm going to look at the place of the Cardinality Estimation Process i ...

  9. SQL Server基础之索引

     索引用于快速找出在某个列中有某一特定值的行,不使用索引,数据库必须从第一条记录开始读完整个表,直到找出相关的行.表越大,查询数据所花费的时间越多,如果表中查询的列有一个索引,数据库能快速到达一个位置 ...

最新文章

  1. 如果我要....(生活版)
  2. equals()和==
  3. psql error: psql: symbol lookup error: psql: undefined symbol: PQconnectdbParams
  4. 移动端工程架构与后端工程架构的思想摩擦之旅(1)
  5. 3.过滤——比较过滤结果、2D中的移动平均线_2
  6. java并发包作者lee_Java的一些并发包
  7. 多模态 | 复旦推出跨视觉语言模态预训练模型,并达到SOTA
  8. rk3399_android7.1平台调试sensor流程记录
  9. sql server2008数据库迁移的两种方案
  10. 关于ibatis中sqlMap配置文件中使用到,的处理
  11. ServiceNow常用角色和分组
  12. 教你在Windows自带的微软拼音输入法中用上小鹤双拼方案
  13. 干货 | 携程数据血缘构建及应用
  14. VTK源码阅读--VTK里的智能指针vtkSmartPointer类
  15. 南明区建成呼叫座席11710席
  16. win10注册表损坏开机蓝屏修复
  17. 算法(Java实现)-算法的时间复杂度和空间复杂度
  18. linux动画制作软件,你也可以成为设计师!宫崎骏御用2D动画制作软件
  19. ASP.Net0626快播影院视频网的设计与实现
  20. unable to dequeue a cell with identifier xxx - must register a nib or a class fo

热门文章

  1. mysql保存中文异常Incorrect string value: '\xE4\xBD\xA0\xE5\xA5\xBD' for column'
  2. h5 先加载小图_【3dmax】小图渲大图(光子贴图的调用)
  3. android gridview item 边框,Android实现为GridView添加边框效果
  4. php ssh2函数,SSH2 函数 - PHP 7 中文文档
  5. ddr4单颗粒最大_Zynq UltraScale +系列之“DDR4接口设计”
  6. java 线程栈空间_java线程的内存不包含在JVM堆与栈中
  7. Mysql、Oracle、SQLServer等数据库参考文档免费分享下载
  8. VS2013怎么给实体类的属性自动生成set和get方法
  9. select设置默认文字,不出现在下拉框中
  10. SpringBoot整合spring-ws开发webservice接口(全流程详细教程)