PLSQL_案例优化系列_推导SQL优化的总体思路和误区(案例1)
2012-10-01 Created By BaoXinjian
一、摘要
从案例中推导SQL优化的总体思路与误区
1. 缺乏对讹传的辨识力
2. 不具备做事的意识
3. 不会依据场景选择技术
4. 未将需求最小化
5. 忽略SQL改造的等价性
6. 不识需求是顶级优化
二、缺乏对讹传的辨识力
1. Count(*) 与 Count(列)的误区
(1). 误区
COUNT(*)比COUNT(列)更慢。项目组必须用COUNT(列),不准用COUNT(*),谁用扣谁钱。
COUNT(*)用不到索引,COUNT(列)才能用到。
COUNT(*)是统计出全表的记录,是吞吐量的操作,肯定用不到索引。
(2). 结论
原来优化器里的算法是这么玩的,列的偏移量决定性能,列越靠后,访问的开销越大。
由于count(*)的算法与列偏移量无关,所以count(*)最快,count(最后列)最慢。
2. SQL编写顺序的误区
(1). 误区 - 表的查询顺序
Oracle的解析器按照从右到左的顺序处理From的表名,因此From子句中写在最后的表将最先被处理。
在From子句中包含多个表的情况下,必须选择记录条数最少的表作为基础表。
(2). 误区 - Where子句的连接顺序
Oracle采用自下而上的顺序解析Where子句,根据这个原理,当Where子句的有多个表连接时,Where子句排在最后的表应该是返回行数最少的表,有过滤条件的子句放在Where子句的最后
(3). 结论
基于RBO或许是如此,基于CBO时代,早就不是如此了,过时了。
3. IN 于EXISTS之争的误区
(1). 误区
在子查询中,Not In z子句将执行一个内部的排序和合并,无论在哪种情况下,Not In都是最低效的(因为对子查询的表执行了一个全表便利),使用NOt Exists子句有效利用索引
(2). 结论
一般来说,anti的反连接算法比filter更高效,但是在10g时,Oracle的这个算法不完善,必须要制定非空,才可以让not in 用anti算法。
在11g的时候,这个情况已经改变了,无论not in 还是not exists,无论是否列为空,都可以走到Oracle比较先进高效的anti反连接算法。
三、不具备做事的意识
1. 避免SQL中的函数调用有啥好处
2. 减少SQL中的函数调用有何思路
3. 集合写法能给性能提升多少
4. 只取你所需的列,访问视图变更快了
5. 只取你所需的列,索引读无需回表了
6. 只取你所需的列,表连接访问提速了
7. 催人泪下,拖垮生产系统的超长慢SQL
8. 出乎意料,SQL优化改写的飞跃性想法
9. 难以置信,让你不相信自己眼睛的SQL
四、不会依据场景选择技术
1. 从某出账相关案例谈索引与更新
2. 建索引引发锁表带来的悲惨故事
3. 建索引导致排序引发的性能风波
五、未将需求最小化
六、忽略SQL改造的等价性
1. Insert 多表插入的玄与机
2. Max及Min 写法的分与合
3. In和><写法之间的同与异
4. Count 列和*结论的对与错
七、不识需求是顶级优化
Thanks and Regards
参考:梁敬彬基于案例学SQL优化培训视频学习笔记
技术交流,技术讨论,欢迎加入
Technology Blog Created By Oracle ERP - 鲍新建