Sql Server优化之索引提示----我们为什么需要查询提示,Sql Server默认情况下优化策略选择的不足

原文:Sql Server优化之索引提示----我们为什么需要查询提示,Sql Server默认情况下优化策略选择的不足

环境:

  Sql Server2012 SP3企业版,Windows Server2008 标准版

 

问题由来:

最近在做DB优化的时候,发现一个存储过程有非常严重的性能问题,

由于整个SP整体逻辑是一个多表关联的复杂的查询,整体结构比较复杂的,通过的分析和尝试,

最后发现问题出在其中一个大表的查询上实现方式上,

因为这个大表上的意外的执行方式,导致其他表无法被驱动,其他表也是表扫描的方式参与join

导致后面整个表之间join以及查询编译出来一系列极其低效的执行效果(不合理的执行计划)

 

这里单独将这个大表的查询提取出来作分析

下面就是我说的大表的这一步在默认情况下的执行情况,

这个表当时数据量是3000W条,符合查询条件的数据在50W左右(一个月的数据量),

 

不加索引提示下的执行情况(测试之前都DBCC dropcleanbuffer 清理缓存):

 

因为考虑到结果集比较大,SSMS结果窗口加载数据耗时比较长

我将结果Insert到临时表的目的是减少SSMS加载数据的时间,更注重查询内部计算

 

如下是sql查询执行信息

 

执行计划情况

 

可以看到它走了一个跟查询字段无关的普通索引的index scan的执行计划,

 

 

 

加上索引提示的执行情况:

 

如果加一个查询列上的索引的查询提示,会发现性能上有一个比较明显的提升

当加上查询索引提示之后,2s中就完成了,比上面默认没有索引提示的方式提高了4倍

 

执行计划信息

 

 

这里就有一个问题,默认情况下为什么没有采用索引查找的方式,而采用了全表扫描的方式?

 如果没猜错的话,很可能有人跟我一样,是认为统计信息没有更新,索引碎片之类导致的

 这个查询非常简单,到底是不是索引统计信息,或者索引碎片之类的引起的呢?

 这个倒是好办,对这个表上的所有索引全部重建(rebuild),同时也会促使统计信息的更新。

 

然后继续测试,问题依旧!!!

 

基本上可以认为,外界条件没有额外干扰的情况下,Sql Server 始终没有选择一个执行速度较快的执行计划,

之所以说Sql Server没有选择执行速度较快的执行计划,而不是说最优的,是因为这个执行计划是没办法直接去评判的,

如果你注意的话,会发现:

不加索引提示的时候:逻辑读是:589689,物理读是589723

加了索引提示的时候,逻辑读是:1992328,但是真正的物理读并不多,只有11229+2042

                逻辑读的增加是在内存中作计算的时候产生的

但是这并不影响后者执行时间更短,

因为后者还有一个内存授予(Memory Grant)一个211M的物理内存用来暂存中间结果集来以更高效的方式来执行

所以我前面说Sqlserver没有选择“执行速度较快”的执行计划,而不是说最优化的执行计划,

因为后者执行更快,但是耗费了更多的服务器资源,前者执行较慢,但是没有耗费很多系统资源。

 

 最优化的是一个很难用一棒子打死的方式去界定的,到底是以执行时间为评判,还是以资源消耗为评判?

我想sqlserver是以综合考量去评价的吧,出现这种情况,我只能推断:默认情况下,评估执行计划的时候,IO的系数在计算中的权重更大

 

如果服务器资源充足的情况下:

  肯定宁愿为其提供充足资源去让其更快地执行以相应应用程序的请求

如果服务器资源不够充足的情况下:

  这个SQl的运行需要这么多内存,

  可能就需要为了申请到(比第一种执行方式)足够多的内存而造成更长时间的等待(这里不细说,比如memory grants pending)

  此时,还不如让他慢慢执行,好歹还能跑出来结果。

 

这种究竟哪种方式好,哪种方式不好,很难有一个定论,一切都要根据具体情况来定,

数据库自身不太可能在任何情况下都作出最最明智的选择,这大概也就是各种关系数据库预留给用户一些查询提示的原因吧。

 

总结: 

  以上粗浅地根据一个遇到的实例案例,通过认为改变默认情况下的执行计划来观察对比sql的执行效率,在我们对数据库进行性能调优时提供一种可参考的方法

  也能够帮助我们认识Sql Server在选择执行计划时候的一些特点,以帮助我们更加有效地使用Sql Server数据库。

 

时间: 2024-08-30 14:50:42

Sql Server优化之索引提示----我们为什么需要查询提示,Sql Server默认情况下优化策略选择的不足的相关文章

浅谈blogcms系统默认情况下的seo优化方法

任何一个程序都不可能尽善尽美,而博客系统默认情况下的seo效果也没有完全发挥出来,笔者的博客地址原来是在主域名的一个子目录里,因为子目录或二级域名的自然权重排名没有优势,所以无奈之下把博客迁移到了主域名之下这也增加了网站运营成本,无形中也加大了后期的维护管理工作,所谓有的放矢想要有给力的排名必须是要付出才能有所回报的.很多核心重点工作第一步如果没有确立一个标准那么在后续工作中那是相当纠结的一件事,李正seo顾问提醒诸位上线一个网站之前一定必须先制定好关键性的网站结构,否则在产生排名之后想要改动那

【HIBERNATE框架开发之九】HIBERNATE 性能优化笔记!(遍历、一级/二级/查询/缓存、乐观悲观锁等优化算法)

本站文章均为 李华明Himi 原创,转载务必在明显处注明:  转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/hibernate/825.html 1.   循环分页或者循环进行部分读取处理数据的时候,使用 session.clear() ;   2.    对应1+N(N+1)问题使用如下解决方式: 1): 使用createCriteria进行查询(join fetch) 2):HQL -> join fetch 3): 使用@fetch设置LAZ

SQL Server通过整理索引碎片和重建索引提高速度

本文章转载:http://database.51cto.com/art/201108/282408.htm SQL Server数据库中,当索引碎片太多时,就会拖慢数据库查询的速度.这时我们可以通过整理索引碎片和重建索引来解决,本文我们主要就介绍了这部分内容,希望能够对您有所帮助.     SQL Server数据库操作中,当数据库中的记录比较多的时候,我们可以通过索引来实现查询.但是当索引碎片太多的时候,就会很严重地影响到查询的速度.这时候我们可以采取两种方法来解决:一种时整理索引碎片,另一种

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

原文:SQL Server 优化---为什么索引视图(物化视图)需要with(noexpand)强制查询提示   本文出处:http://www.cnblogs.com/wy123/p/6694933.html    第一次通过索引视图优化SQL语句,以及遇到的一些问题,记录一下.   语句分析 最近开发递交过来一个查询统计的SQL,说是性能有问题,原本执行需要4-5秒钟,这个业务本身对性能要求又比较critical,期望是在1s之内在用尽各种办法之后(执行计划,统计信息,索引,改写SQL,临时

Sql server优化其索引的小技巧

关于索引的常识:影响到数据库性能的最大因素就是索引.由于该问题的复杂性,我只可能简单的谈谈这个问题,不过关于这方面的问题,目前有好几本不错的书籍可供你参阅.我在这里只讨论两种SQL Server索引,即clustered索引和nonclustered索引.当考察建立什么类型的索引时,你应当考虑数据类型和保存这些数据的column.同样,你也必须考虑数据库可能用到的查询类型以及使用的最为频繁的查询类型. 索引的类型 如果column保存了高度相关的数据,并且常常被顺序访问时,最好使用cluster

浅析SQL Server性能优化之索引运算

技术准备 基于SQL Server2008R2版本,利用微软的一个更简洁的案例库(Northwind)进行解析. 简介 所谓的索引应用就是在我们日常写的T-SQL语句中,如何利用现有的索引项,再分析的话就是我们所写的查询条件,其实大部分情况也无非以下几种: 1.等于谓词:select ...where...column=@parameter 2.比较谓词:select ...where...column> or < or <> or <= or >= @paramete

SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行)

原文:SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行) 前言 前面几篇我们分析了关于SQL Server关于性能调优的一系列内容,我把它分为两个模块. 第一个模块注重基础内容的掌握,共分6篇文章完成,内容涵盖一系列基础运算算法,详细分析了如何查看执行计划.掌握执行计划优化点,并一一列举了日常我们平常所写的T-SQL语句所会应用的运算符.我相信你平常所写的T-SQL语句在这几篇文章中都能找到相应的分解运算符. 第二个模块注重SQL Server执行T-SQL语句的时候

SQL Server已分区索引的特殊指导原则(3)

一.前言 在MSDN上看到一篇关于SQL Server 表分区的文档:已分区索引的特殊指导原则,如果你对表分区没有实战经验的话是比较难理解文档里面描述的意思.这里我就里面的一些概念进行讲解,方便大家的交流. SQL Server 解读[已分区索引的特殊指导原则](1)- 索引对齐 SQL Server 解读[已分区索引的特殊指导原则](2)- 唯一索引分区 二.解读 [对非聚集索引进行分区] "对唯一的非聚集索引进行分区时,索引键必须包含分区依据列.对非唯一的非聚集索引进行分区时,默认情况下 S

SQL Server已分区索引的特殊指导原则(2)- 唯一索引分区

一.前言 在MSDN上看到一篇关于SQL Server 表分区的文档:已分区索引的特殊指导原则,如果你对表分区没有实战经验的话是比较难理解文档里面描述的意思.这里我就里面的一些概念进行讲解,方便大家的交流. 二.解读 [对唯一索引进行分区] "对唯一索引(聚集或非聚集)进行分区时,必须从唯一索引键使用的分区依据列中选择分区依据列.此限制将使 SQL Server 只调查单个分区,以确保表中不存在重复的新键值.如果分区依据列不可能包含在唯一键中,则必须使用 DML 触发器,而不是强制实现唯一性.&