[优化] SQL执行计划

1. 流聚合:select count(0) from dbo.User_Cookie_Mapping

    * 所有的聚合函数(count(),max())流聚合不会有IO消耗,只会有CPU消耗

2. 计算标量:根据行中现有的值计算新值,如Count()函数,多一行,行数就+1
    * Max(),Min()之外的聚合函数,要求流聚合操作后加一个计算标量
 
3. 散列聚合(哈希匹配):对于加了 Group by 的语句
    select count(0),UserID from dbo.User_Cookie_Mapping group by UserID  

    *在内存中建立好哈希表后,会按照group by后面的值作为键,然后依次处理集合中的每条数据,当键在散列表不存在时,向散列表添加类目,若存在则按照规则(比如count,sum等)计算散列表中的值。
4. 排序:当3中,表数据量比较小时
select CategoryID,count(0) from dbo.TB_Topic group by CategoryID 
 
5. 嵌套循环连接
select * from TB_Order o
inner join TB_OrderLog ol on o.ID=ol.OrderID OPTION(querytraceon 8649)  
6. 合并连接:相比较嵌套循环链接,每个表只扫一次,但是需要连接双方有序(排序)
select * from TB_Order o
inner join TB_OrderLog ol on o.ID=ol.OrderID OPTION(merge join)  
7. 哈希链接(散列连接、哈希匹配):同合并连接一样,连接双方只需各扫一次,它是通过再内存中建立散列表来实现,比较消耗内存,如果内存不足会消耗tempdb,但不像合并连接需要双方有序
select * from TB_Order o
inner join TB_OrderLog ol on o.ID=ol.OrderID 
* 需要删除俩个表的所有索引才能看到,应为改成本比较高

 
 
疑问:
1. 当我们执行SQL语句 select * from Person 的 时候,如果该表不建任何索引,那么SQL执行计划 中可以看到是 表扫描 ;但是如果建了聚集索引,执行计划中就会显示聚集索引扫描,这俩个有什么区别呢?
 


解答:性能上没区别,之所以由 表扫面 变为了 聚集索引扫描,是因为当你建了聚集索引后,表的数据存储顺序要和聚集索引的顺序一致,该表的数据结构由 堆表 变为了聚集表,表扫描是堆表上逐行遍历,聚集索引扫描是遍历的聚集索引,聚集索引也是B+树结构,叶子节点就是数据节点,所以性能上没什么太大差别,这一点从查询的时候IO分析就可以看得出来。但是当有了Where条件后,性能就不一样了,比如 select * from Personwhere ID>432528
 
 
 
2. 有时候我们在看执行计划的时候遇到这么不解的问题,比如给Name列建非聚集索引  select Name from Person ,会看到执行计划走非聚集索引;
 
 
 
 
 
 

但是,当我们再多添加几个查询列后,select Name,ID,AddDate from Person  情况发生了改变。执行计划不走非聚集索引,而是表扫描

解答:当非聚集索引不能覆盖所查询的列时,就会走表扫描或聚集索引扫描
 
3. 这也是平常比较迷惑的一个问题,键查找 或 RID查找。
解答:就是当我们根据索引查找到的数据不能满足所要匹配的列时,会先查到该行,找到行号或者键值在去找对应的数据
 
 
 
 
执行计划进阶:
 
  • 根据传入的SQL文本,解析表名、视图名、存储过程名等,生成查询文本树
  • 优化简化,将子查询转化为等效的连接查询,去掉不必要的连接
  • 根据数据库的统计信息,进行基于成本的评估
 
这一过程,就是我们所写的SQL语句所经历的一部分,这个过程中CPU是消耗的。所以在第一次分析编译后,会将最适合的执行计划缓存起来,方便下次使用。这里需要说下“基于成本的优化”,这里主要依赖于数据库的统计信息,基于成本评估出的执行计划不一定是最佳的,因为评估也需要消耗。
 
下面是两个查询执行计划缓存的存储过程:
SELECT * FROM SYS.DM_EXEC_CACHED_PLANS
SELECT * FROM SYS.DM_OS_MEMORY_CACHE_COUNTERS  
 
 
另外:同一SQL语句不通的参数可能造成使用不同的执行计划,为同一起见,我们最好统一使用参数化查询,而不是拼SQL语句,这样后一个SQL语句就会重用前一个的执行计划,而不需要再去做分析和编译的工作,节省了CPU开销。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2019-04-30 15:28  NCat  阅读(344)  评论(0)    收藏  举报