SQL 性能的优化

SQL 性能的优化
------------------------------------------
1.1 IN 操作符

    用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。

    但是用IN的SQL性能总是比较低的,从ORACLE执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别:

    ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用

    多个表的连接方式查询。

    由此可见用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。

    推荐方案:在业务密集的SQL当中尽量不采用IN操作符而使用EXISTS。

    1.2 NOT IN操作符

    此操作是强列推荐不使用的,因为它不能应用表的索引。

    推荐方案:用NOT EXISTS代替

    1.3 <> 操作符(不等于)

    不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。

    推荐方案:用其它相同功能的操作运算代替,如

    a<>0 改为 a>0 or a<0
    a<>’’ 改为 a>’’

    1.4 IS NULL 或IS NOT NULL操作(判断字段是否为空)

    判断字段是否为空一般是不会应用索引的,因为B树索引是不索引空值的。

    推荐方案:

    用其它相同功能的操作运算代替,如

    a is not null 改为 a>0 或a>’’等。

    不允许字段为空,而用一个缺省值代替空值。

    1.5 > 及 < 操作符(大于或小于操作符)

    大于或小于操作符一般情况下是不用调整的,因为它有索引就会采用索引查找,但有的情况下可以对它进行优化,

    如一个表有100万记录,一个数值型字段A,30万记录的A=0,30万记录的A=1,39万记录的A=2,1万记录的A=3。

    那么执行A>2与A>=3的效果就有很大的区别了,因为A>2时ORACLE会先找出为2的记录索引再进行比较,而A>=3时ORACLE则直接找到=3的记录

    索引。

    1.6 LIKE操作符

    LIKE操作符可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用得不好则会产生性能上的问题,

    如LIKE ‘%5400%’ 这种查询不会引用索引,而LIKE ‘X5400%’则会引用范围索引。

    一个实际例子:用YW_YHJBQK表中营业编号后面的户标识号可来查询营业编号 YY_BH LIKE ‘%5400%’ 这个条件会产生全表扫描,

    如果改成YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 则会利用YY_BH的索引进行两个范围的查询,性能肯定大大提高。

    1.7 UNION操作符

    UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。

    select * from gc_dfys
    union
    select * from ls_jg_dfys

    这个SQL在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会

    导致用磁盘进行排序。

    推荐方案:

    采用UNION ALL操作符替代UNION,因为UNION ALL操作只是简单的将两个结果合并后就返回。

    select * from gc_dfys
    union all
    select * from ls_jg_dfys

    1.8 group by用法

    Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句。

    select topicid,userid,sum(counter) from cis_topic_stat group by rollup(topicid,userid);

    也就是说,如果是ROLLUP(A, B, C)的话,首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP BY,

    然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。

    select topicid,userid,sum(counter) from cis_topic_stat group by cube(topicid,userid);

    和ROLLUP相比,CUBE又增加了对STATUS列的GROUP BY统计。

    如果是GROUP BY CUBE(A, B, C),则首先会对(A、B、C)进行GROUP BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),

    最后对全表进行GROUP BY操作。

    1.9 如何使用Hint提示

    在select/delete/update后写/*+ hint */

    如 select /*+ index(TABLE_NAME INDEX_NAME) */ col1...

    注意/*和+之间不能有空格

    如用hint指定使用某个索引

    select /*+ index(cbotab) */ col1 from cbotab;
    select /*+ index(cbotab cbotab1) */ col1 from cbotab;
    select /*+ index(a cbotab1) */ col1 from cbotab a;

    其中

    TABLE_NAME是必须要写的,且如果在查询中使用了表的别名,在hint也要用表的别名来代替表名;

    INDEX_NAME可以不必写,Oracle会根据统计值选一个索引;

    如果索引名或表名写错了,那这个hint就会被忽略;
 
1. 前言 5 1.1 目的 5 1.2 文档说明 5 1.3 词汇表 5 1.4 参考资料 5 2. PLSQL程序优化原则 6 2.1 导致性能问题的内在原因 6 2.2 PLSQL优化的核心思想 6 2.3 ORACLE优化器 6 2.4 PLSQL优化 7 2.4.1 选择最有效率的表名顺序 7 2.4.2 WHERE子句中的连接顺序 8 2.4.3 SELECT子句中避免使用 ‘ * ‘ 8 2.4.4 用EXISTS替代IN 8 2.4.5 用NOT EXISTS替代NOT IN 9 2.4.6 用表连接替换EXISTS 9 2.4.7 用EXISTS替换DISTINCT 10 2.4.8 减少对表的查询 10 2.4.9 避免循环(游标)里面嵌查询 11 2.4.10 尽量用union all替换union 13 2.4.11 使用DECODE函数来减少处理时间 13 2.4.12 group by优化 13 2.4.13 尽量避免用order by 14 2.4.14 用Where子句替换HAVING子句 14 2.4.15 使用表的别名(Alias) 14 2.4.16 删除重复记录 14 2.4.17 COMMIT使用 15 2.4.18 减少多表关联 15 2.4.19 批量数据插入 15 2.5 索引使用优化 16 2.5.1 避免在索引列上使用函数或运算 16 2.5.2 避免改变索引列的类型. 17 2.5.3 避免在索引列上使用NOT 17 2.5.4 用>=替代> 18 2.5.5 避免在索引列上使用IS NULL和IS NOT NULL 18 2.5.6 带通配符(%)的like语句 18 2.5.7 总是使用索引的第一个列 19 2.5.8 多个平等的索引 19 2.5.9 不明确的索引等级 19 2.5.10 自动选择索引 19 2.5.11 使用提示(Hints) 19 2.5.12 表上存在过旧的分析 20 2.5.13 表上存在并行 21 2.5.14 关于索引建立 21 3. PLSQL程序性能问题测试方法 21 3.1 性能问题分析 21 3.2 EXPAIN PLAN分析索引使用 22 3.3 TOPSQL分析 24 3.4 针对性语句搜索 28 3.5 后台存储过程跟踪 29 3.6 性能监控 30 4. 性能测试工具设计思想 31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值