最近系统的研究了一下ORACLE SQL语句性能调优,在此大言不惭的得出一个观点——网上很多性能调优的结论都是错误的或者不周全的。
现在的DBA大牛些都太低调了,不出来斧正一下,小弟来借这个机会吐槽一下,说的不对,欢迎拍砖,特别是版本问题:

转入正题:
网络上大部分结论“可能”适用于ORACLE8或者以前版本(小弟出道晚没见过ORACLE
8),但是针对9i及以后的版本,很多结论都是欠周全的。

下面举几个最常见的问题:

错误观点1、什么时候用IN 什么时候用EXISTS? 子查询数据量少用IN
量多用EXISTS

如果你说
半连接子查询返回数据少的时候用IN,返回数据多的时候用EXISTS,那么恭喜你,你错了 。

纠正:不要轻信网上是如何说的,学了ORACLE最大的感触就是不要记结论,自己实践了才知道,创建两张表练习一下,由于篇幅原因,我这里还是给一个结论——通过执行计划看到,大多数情况下IN
和EXISTS的效率是一模一样的,只是有时候EXISTS不能 SUBSTRING UNNESTING,导致执行计划走FILTER
,执行计划一旦走了FILTER,驱动表是改变不了的(12C
能不能我不清楚),想象一下,主表是1000W,子表返回20条,由于驱动表改变不了,很有可能是大表驱动小表了。
错误观点2、NOT IN 与 NOT EXISTS 子查询量少用NOT
IN 否则用NOT EXISTS

NOT
IN 与 NOT EXISTS也是一个道理,但是要注意NULL的情况,NULL容易导致无法使用索引,可以创建函数索引或与常量一起做一个组合索引。

错误观点3、WHERE条件有先后顺序,后面的先执行或前面的先执行
如果过滤数据量基本持平的话,两个不同的谓词过滤条件可能会因为脚本的编写而有先后顺序,但是不要因此推断出“WHERE条件有先后顺序,后面的先执行或前面的先执行”,哪个先执行时CBO根据统计信息分析之后说了算,下面两条语句的执行计划的逻辑读都是一样的

可以通过下面的列子来测试一下执行效果

 
  1. CREATE TABLE TEST02 AS SELECT * FROM DBA_OBJECTS;
  2. SELECT COUNT(*) FROM TEST02 A WHERE A.OWNER='SYS' AND A.OBJECT_ID=29 ;
  3. SELECT COUNT(*) FROM TEST02 A WHERE A.OBJECT_ID=29 AND A.OWNER='SYS' ;
错误观点4、FROM 语句有左右顺序 所以要注意书写顺序

同第3点一样,给个例子——下面两个语句的执行计划也是一样的,ORACLE知道哪个该做驱动表
,因此没有区别

 
  1. CREATE TABLE T1 AS SELECT LEVEL AS ID FROM DUAL CONNECT BY LEVEL<=10000;--大表
  2. CREATE TABLE T2 AS SELECT LEVEL AS ID FROM DUAL CONNECT BY LEVEL<=10;--小表
  3. SELECT COUNT(1) FROM T1,T2;
  4. SELECT COUNT(1) FROM T2,T1;
  5. 执行计划
  6. ----------------------------------------------------------
  7. Plan hash value: 4259280259
  8. ----------------------------------------------------------------------
  9. | Id | Operation | Name | Rows | Cost (%CPU)| Time |
  10. ----------------------------------------------------------------------
  11. | 0 | SELECT STATEMENT | | 1 | 60 (2)| 00:00:01 |
  12. | 1 | SORT AGGREGATE | | 1 | | |
  13. | 2 | MERGE JOIN CARTESIAN| | 100K| 60 (2)| 00:00:01 |
  14. | 3 | TABLE ACCESS FULL | T2 | 10 | 3 (0)| 00:00:01 |
  15. | 4 | BUFFER SORT | | 10000 | 57 (2)| 00:00:01 |
  16. | 5 | TABLE ACCESS FULL | T1 | 10000 | 6 (0)| 00:00:01 |
  17. ----------------------------------------------------------------------
  18. 统计信息
  19. ----------------------------------------------------------
  20. 0 recursive calls
  21. 0 db block gets
  22. 22 consistent gets
  23. 0 physical reads
  24. 0 redo size
  25. 527 bytes sent via SQL*Net to client
  26. 519 bytes received via SQL*Net from client
  27. 2 SQL*Net roundtrips to/from client
  28. 1 sorts (memory)
  29. 0 sorts (disk)
  30. 1 rows processed
错误观点5、避免使用OR来连接条件,否则导致引擎放弃使用索引而进行全表扫描

如:SELECT
ID FROM T WHERE NUM=10 OR NUM=11 会全表扫描

下面来个例子,

 
  1. CREATE TABLE TEST02 AS SELECT * FROM DBA_OBJECTS;
  2. CREATE INDEX TEST_02_IDX_01 ON TEST02 (OBJECT_ID);
  3. ALTER SESSION SET OPTIMIZER_FEATURES_ENABLE='9.2.0';
  4. SELECT COUNT(*) FROM TEST02 A WHERE A.OBJECT_ID=28 OR A.OBJECT_ID=29 ;

查看执行计划

 
  1. 执行计划
  2. ----------------------------------------------------------
  3. Plan hash value: 3430686514
  4. ---------------------------------------------------------------------
  5. | Id | Operation | Name | Rows | Bytes | Cost |
  6. ---------------------------------------------------------------------
  7. | 0 | SELECT STATEMENT | | 1 | 5 | 2 |
  8. | 1 | SORT AGGREGATE | | 1 | 5 | |
  9. | 2 | INLIST ITERATOR | | | | |
  10. |* 3 | INDEX RANGE SCAN| TEST_02_IDX_01 | 2 | 10 | 2 |
  11. ---------------------------------------------------------------------
  12. Predicate Information (identified by operation id):
  13. ---------------------------------------------------
  14. 3 - access("A"."OBJECT_ID"=28 OR "A"."OBJECT_ID"=29)

实际上使用了索引

总结:网上的经验可能是某些人看了某些文章,然后在特定的场景下测试了效果一样,甚至没有测试就以讹传讹,容易误导人,Oracle脚本中有多优化的观点不同的版本等场景下因为执行计划的不同 而导致结论不一样,因此要根据实际出发,最好再亲自测一下,DBA不会告诉你这么的,因为他们自己还要混饭吃的。
不过说不定我这盘文章中有些结论也是错的,自己测一遍才知道
其实ORACLE优化还是有很多小细节需要注意的,也有很多的方法,有机会的话再与大家分享

Oracle优化网上常见的5个错误观点的更多相关文章

  1. oracle数据库管理系统常见的错误(一)

    oracle数据库管理系统常见的错误之一如下: Listener refused the connection with the following error:ORA-12519, TNS:no a ...

  2. adb使用过程常见的几种错误总结

    问题1:Failure [INSTALL_FAILED_ALREADY_EXISTS] 问题原因:该程序已存在. 解决方法:增加-r参数,即可成功覆盖安装 问题2:Failure [INSTALL_F ...

  3. Oracle优化-SQL_TRACE

    思维导图 Oracle优化10-SQL_TRACE解读 Oracle优化11-10046事件 概述 当我们想了解一条SQL或者是PL/SQL包的运行情况时,特别是当他们的性能非常差时,比如有的时候看起 ...

  4. Oracle 优化器

    http://blog.csdn.net/it_man/article/details/8185370一.优化器基本知识   Oracle在执行一个SQL之前,首先要分析一下语句的执行计划,然后再按执 ...

  5. ORACLE优化器RBO与CBO介绍总结

    RBO和CBO的基本概念 Oracle数据库中的优化器又叫查询优化器(Query Optimizer).它是SQL分析和执行的优化工具,它负责生成.制定SQL的执行计划.Oracle的优化器有两种,基 ...

  6. Oracle优化总结

    本文主要从大型数据库ORACLE环境四个不同级别的调整分析入手,分析ORACLE的系统结构和工作机理,从九个不同方面较全面地总结了ORACLE数据库的优化调整方案.关键词 ORACLE数据库 环境调整 ...

  7. Oracle优化的几个简单步骤

    数据库优化的讨论可以说是一个永恒的主题.资深的Oracle优化人员通常会要求提出性能问题的人对数据库做一个statspack,贴出数据库配置等等.还有的人认为要抓出执行最慢的语句来进行优化.但实际情况 ...

  8. mysql 常见的几个错误问题

    Mysql常见的几个错误问题及解决方法: 1.问题: mysql DNS反解:skip-name-resolve 错误日志有类似警告: 点击(此处)折叠或打开 120119 16:26:04 [War ...

  9. oracle优化原则(二)

    SQL优化原则 二.SQL语句编写注意问题 www.2cto.com 下面就某些SQL语句的where子句编写中需要注意的问题作详细介绍.在这些where子句中,即使某些列存在索引,但是由于编写了劣质 ...

随机推荐

  1. [BJOI2018]双人猜数游戏

    题解: 彻彻底底的思维题???还是挺难的.. 首先连样例解释都没给..没看题解搞了很久 大概就是 一个人要根据另一个人的决策来猜数 可以去看洛谷那篇题解的解释 然后我们用$f[A/B][i][j][k ...

  2. centos7 查看ip地址

    命令: ip  address 简写ip  a 过滤出来某个网卡的ip: ip a show ens33 |awk -F ' ' 'NR==3{print$2}'|cut -d / -f1

  3. 10个财务工作中常用的 Excel 万能公式

    1.多条件判断公式 =IF(AND(条件1,条件2...条件n),同时满足条件返回的值,不满足条件返回的值) =IF(OR(条件1,条件2...条件n),同时满足任一条件返回的值,不满足条件返回的值) ...

  4. Python_时间复杂度概念

    时间频度:一个算法中的语句执行次数称为语句频度或时间频度,记为T(n)(T代表次数,n代表问题规模) 时间复杂度:呈现时间频度的变化规律,记为T(n)=O(f(n)) 指数时间:一个问题求解所需的执行 ...

  5. sparkStreaming序列化问题

    执行sparkSTreaming+kafka 报错如下: org.apache.spark.SparkException: Task not serializable ...... Caused by ...

  6. ELK 环境搭建3-Logstash

    一.Logstash是一款轻量级的日志搜集处理框架,可以方便的把分散的.多样化的日志搜集起来,并进行自定义的处理,然后传输到指定的位置,比如某个服务器或者文件或者中间件. 二.搭建 1.因为要涉及到收 ...

  7. Codeforces 830D Singer House 动态规划

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF830D.html 题解 考虑用 $dp[i][j]$ 表示深度为 $i$ 的树里,有 $j$ 条路径的方案数 ...

  8. ZJOI2018 胖 二分 ST表

    原文链接https://www.cnblogs.com/zhouzhendong/p/ZJOI2018Day2T2.html 题目传送门 - BZOJ5308 题目传送门 - LOJ2529 题目传送 ...

  9. Spark中map与flatMap

    map将函数作用到数据集的每一个元素上,生成一个新的分布式的数据集(RDD)返回 map函数的源码: def map(self, f, preservesPartitioning=False): &q ...

  10. mac 命令操作

    内核空间和用户空间 x86架构中将内核地址空间划分三部分:ZONE_DMA.ZONE_NORMAL和 ZONE_HIGHMEM. 自动加载(开机自动启动服务) ln -sfv /usr/local/o ...