原文:http://bbs.landingbj.com/t-0-240353-1.html

1、选用适合的 ORACLE 优化器

2、访问 Table 的方式

3、共享SQL语句

共享的语句必须满足三个条件

1) 字符级的比较,当前被执行的语句和共享池中的语句必须完全相同。

2) 两个语句所指的对象必须完全相同。

3) 两个 SQL 语句中必须使用相同的名字的绑定变量(bind variables)。

4、选择最有效率的表名顺序(只在基于规则的优化器中有效)

ORACLE 的解析器按照从右到左的顺序处理 FROM 子句中的表名,因此 FROM 子句中写在最后的表(基础表 driving table)将被最先处理。在 FROM 子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。

5、WHERE 子句中的连接顺序

ORACLE 采用自下而上的顺序解析 WHERE 子句,根据这个原理,表之间的连接必须写在其他 WHERE 条件之前。

6、SELECT 子句中避免使用 ‘ * ’

当 你想在 SELECT 子句中列出所有的 COLUMN 时,使用动态 SQL 列引用‘*’是一个方便的方法。不幸的是,这是一个非常低效的方法。实际 上,ORACLE 在解析的过程中,会将‘*’依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间。

7、减少访问数据库的次数

当执行每条 SQL 语句时,ORACLE 在内部执行了许多工作:解析 SQL 语句,估算索引的利用率,绑定变量,读数据块等等。由此可见,减少访问数据库的次数,就能实际上减少ORACLE 的工作量。

在 SQL*Plus,SQL*Forms 和 Pro*C 中重新设置 ARRAYSIZE 参数,可以增加每次数据库访问的检索数据量,建议值为 200。

8、使用 DECODE 函数来减少处理时间

使用 DECODE 函数可以避免重复扫描相同记录或重复连接相同的表。

9、整合简单,无关联的数据库访问

10、删除重复记录

最高效的删除重复记录方法:

delete from emp e
where e.rowid > (select min(x.rowid) from emp x where x.emp_no = e.emp_no);

11、用 TRUNCATE 替代 DELETE


删除表中的记录时,在通常情况下,回滚段(rollback segments)用来存放可以被恢复的信息。如果你没有 COMMIT 事
务,ORACLE 会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况)而当运用 TRUNCATE 时,回滚段不再存放任何可被恢
复的信息。当命令运行后,数据不能被恢复。因此很少的资源被调用,执行时间也会很短。TRUNCATE 只在删除全表适
用,TRUNCATE 是 DDL 不是 DML。

12、尽量多使用 COMMIT

COMMIT 所释放的资源:

回滚段上用于恢复数据的信息

被程序语句获得的锁

redo log buffer 中的空间

ORACLE 为管理上述 3 种资源中的内部花费

13、计算记录条数

和一般的观点相反,count(*)比 count(1)稍快,当然如果可以通过索引检索,对索引列的计数仍旧是最快的。例如 COUNT(EMPNO)。

14、用 Where 子句替换 HAVING 子句

避免使用 HAVING 子句,HAVING 只会在检索出所有记录之后才对结果集进行过滤。这个处理需要排序,总计等操作。如果能通过 WHERE 子句限制记录的数目,那就能减少这方面的开销。

15、减少对表的查询

在含有子查询的 SQL 语句中,要特别注意减少对表的查询。

16、通过内部函数提高 SQL 效率

17、使用表的别名(Alias)

当在 SQL 语句中连接多个表时,请使用表的别名并把别名前缀于每个 Column 上。这样一来,就可以减少解析的时间并减少那些由 Column 歧义引起的语法错误。

18、用 EXISTS 替代 IN

在许多基于基础表的查询中,,为了满足一个条件,往往需要对另一个表进行联接。在这种情况下,使用 EXISTS(或 NOT EXISTS)通常将提高查询的效率。

19、用 NOT EXISTS 替代 NOT IN

在子查询中,NOT IN 子句将执行一个内部的排序和合并。无论在哪种情况下,NOT IN都是最低效的,因为它对子查询中的表执行了一个全表遍历。为了避免使用 NOT IN,我们可以把它改写成外连接 Outer Joins,或 NOT EXISTS。

20、用表连接替换 EXISTS

通常来说,采用表连接的方式比 EXISTS 更有效率。

21、用 EXISTS 替换 DISTINCT

当提交一个包含一对多表信息的查询时,避免在 SELECT 子句中使用 DISTINCT。一般可以考虑用 EXIST 替换。

EXISTS 使查询更为迅速,因为 RDBMS 核心模块将在子查询的条件一旦满足后,立刻返回结果。

22、识别‘低效执行’的 SQL 语句

虽然目前各种关于 SQL 优化的图形化工具层出不穷,但是写出自己的 SQL 工具来解决问题始终是一个最好的方法。

23、使用 TKPROF 工具来查询 SQL 性能状态

24、用 EXPLAIN PLAN 分析 SQL 语句

EXPLAIN PLAN 是
一个很好的分析 SQL 语句的工具,它甚��可以在不执行 SQL 的情况下分析语句。通过分析,我们就可以知道 ORACLE 是怎么样连接表,使用
什么方式扫描表(索引扫描或全表扫描)以及使用到的索引名称。你需要按照从里到外,从上到下的次序解读分析的结果。EXPLAIN PLAN 分析的结果
是用缩进的格式排列的,最内部的操作将被最先解读,如果两个操作处于同一层中,带有最小操作号的将被首先执行。NESTED LOOP 是少数不按照上述
规则处理的操作,正确的执行路径是检查对 NESTED LOOP 提供数据的操作,其中操作号最小的将被最先处理。

注:目前许多第三方的工具如 TOAD 和 ORACLE 本身提供的工具如 OMS 的 SQL Analyze都提供了极其方便的 EXPLAIN PLAN 工具。

25、用索引提高效率


引是表的一个概念部分,用来提高检索数据的效率。实际上,ORACLE 使用了一个复杂的自平衡 B-tree 结构。通常,通过索引查询数据比全表扫描
要快。当 ORACLE 找出执行查询和 Update 语句的最佳路径时,ORACLE 优化器将使用索引。同样在联结多个表时使用索引也可以提高效
率。另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证。

除了那些 LONG 或 LONG RAW 数据类型,你可以索引几乎所有的列。通常,在大型表中使用索引特别有效。当然,你也会发现,在扫描���表时,使用索引同样能提高效率。


然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价。索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时,索引本身
也会被修改。这意味着每条记录的 INSERT,DELETE,UPDATE 将为此多付出 4,5 次的磁盘 I/O。因为索引需要额外的存储空间和处
理,那些不必要的索引反而会使查询反应时间变慢。

定期的重构索引是有必要的。

alter index <indexname> rebuild <tablespacename>;

26、索引的操作

ORACLE 对索引有两种访问模式:

1) 索引唯一扫描(INDEX UNIQUE SCAN)

2) 索引范围查询(INDEX RANGE SCAN)

A. 基于一个范围的检索

B. 基于非唯一性索引的检索

27、基础表的选择

基础表(Driving Table)是指被最先访问的表(通常以全表扫描的方式被访问)。根据优化器的不同,SQL 语句中基础表的选择是不一样的。

如果你使用的是 CBO(COST BASED OPTIMIZER),优化器会检查 SQL 语句中的每个表的物理大小,索引的状态,然后选用花费最低的执行路径。

如果你用 RBO(RULE BASED OPTIMIZER),并且所有的连接条件都有索引对应,在这种情况下,基础表就是 FROM 子句中列在最后的那个表

28、多个平等的索引

如果不同表中两个相同等级的索引将被引用,FROM 子句中表的顺序将决定哪个会被率先使用。FROM 子句中最后的表的索引将有最高的优先级。

如果相同表中两个想同等级的索引将被引用,WHERE 子句中最先被引用的索引将有最高的优先级。

29、等式比较和范围比较

当 WHERE 子句中有索引列,ORACLE 不能合并它们,ORACLE 将用范围比较

30、不明确的索引等级

当 ORACLE 无法判��索引的等级高低差别,优化器将只使用一个索引,它就是在 WHERE子句中被列在最前面的。

31、强制索引失效

如果两个或以上索引具有相同的等级,你可以强制命令 ORACLE 优化器使用其中的一个(通过它,检索出的记录数量少)。

32、避免在索引列上使用计算

WHERE 子句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描。这是一个非常实用的规则,请务必牢记。

33、自动选择索引

如果表中有两个以上(包括两个)索引,其中有一个唯一性索引,而其他是非唯一性索引。在这种情况下,ORACLE 将使用唯一性索引,而完全忽略非唯一性索引

34、避免在索引列上使用 NOT

通常,我们要避免在索引列上使用 NOT,NOT 会产生在和在索引列上使用函数相同的影响。当 ORACLE 遇到 NOT,会停止使用索引转���执行全表扫描。

35、用>=替代>

36、用 UNION 替换 OR(适用于索引列)

37、用 IN 来替换 OR

38、避免在索引列上使用 IS NULL 和 IS NOT NULL

避免在索引中使用任何可以为空的列,ORACLE 将无法使用该索引。对于单列索引,如’果列包含空值,索引中将不存在此记录。对于复合索引,如果每个列都为空,索引中同样不存在此记录。如果至少有一个列不为空,则记录存在于索引中。

39、总是使用索引的第一个列

40、ORACLE 内部操作

41、用 UNION-ALL 替换 UNION(如果有可能的话)

当 SQL 语句需要 UNION 两个查询结果集合时,这两个结果��合会以 UNION-ALL 的方式被合并,然后在输出最终结果前进行排序。如果用 UNION ALL 替代 UNION,这样排序就不是必要了,效率就会因此得到提高。

NION 将对结果集合排序,这个操作会使用到 SORT_AREA_SIZE 这块内存。对于这块内存的优化也是相当重要的。

42、使用提示(Hints)

对于表的访问,可以使用两种 Hints:FULL 和 ROWID。

43、用 WHERE 替代 ORDER BY

ORDER BY 子句只在两种严格的条件下使用索引。

1) ORDER BY 中所有的列必须包含在相同的索引中并保持在索引中的排列顺序;

2) ORDER BY 中所有的列必须定义为非空。

WHERE 子句使用的索引和 ORDER BY 子句中所使用的索引不能并列。

44、避免改变索引列的类型

为了避免 ORACLE 对你的 SQL 进行隐式的类型转换,最好把类型转换用显式表现出来。注意当字符和数值比较时,ORACLE 会优先转换数值类型到字符类型。

45、需要当心的 WHERE 子句

46、连接多个扫描

如果你对一个列和一组有限的值进行比较,优化器可能执行多次扫描并对结果进行合并连接

47、CBO 下使用更具选择性的索引

48、避免使用耗费资源的操作

有 DISTINCT,UNION,MINUS,INTERSECT,ORDER BY 的 SQL 语
句会启动 SQL引擎执行耗费资源的排序(SORT)功能。DISTINCT 需要一次排序操作,而其他的至少需要执行两次排序。例如,一
个 UNION 查询,其中每个查询都带有 GROUP BY 子句,GROUP BY 会触发嵌入排序(NESTED SORT); 这样,每个查询需
要执行一次排序,然后在执行 UNION 时,又一个唯一排序(SORT UNIQUE)操作被执行而且它只能在前面的嵌入排序结束后才能开始执行。嵌入
的排序的深度会大大影响查询的效率。通常,带有 UNION,MINUS,INTERSECT 的 SQL 语句都可以用其他方式重写。

49、优化 GROUP BY

50、使用日期当心

使用日期时,需要注意如果有超过 5 位小数加到日期上,这个日期会进到下一天!

51、使用显式的游标(CURSORs)

使用隐式的游标,将会执行两次操作:第一次检索记录,第二次检查 TOO MANY ROWS这个 exception;而显式游标不执行第二次操作。

52、优化 EXPORT 和 IMPORT

53、分离表和索引

总 是 将 你 的 表 和 索 引 建 立 在 不 同 的 表 空 间 内 (TABLESPACES) 。 决 不 要 将 不 属 于ORACLE 内部系统的对象存放到 SYSTEM 表空间里。同时,确保数据表空间和索引表空间置于不同的硬盘上。

Oracle SQL优化原则的更多相关文章

  1. Oracle SQL 优化原则(实用篇)

    由于SQL优化优化起来比较复杂,并且还受环境限制,在开发过程中,写SQL必须遵循以下几点原则: 1.Oracle 采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他Where ...

  2. ORACLE 数据库优化原则

    ORACLE 数据库优化原则 一.SQL语句用大写的: 因为Oracle总是先解析SQL语句,把小写的字母转换成大写的再厉行. 二.避免在索引列上利用NOT等闲 我们要避免在索引列上利用NOT, NO ...

  3. oracle sql 优化大全

    转自: http://panshaobinsb.iteye.com/blog/1718233 http://yulimeander.blog.sohu.com/115850824.html 最近遇到了 ...

  4. 我的mysql数据库sql优化原则

    原文 我的mysql数据库sql优化原则 一.前提 这里的原则 只是针对mysql数据库,其他的数据库 某些是殊途同归,某些还是存在差异.我总结的也是mysql普遍的规则,对于某些特殊情况得特殊对待. ...

  5. Oracle SQL优化[转]

    Oracle SQL优化 1. 选用适合的ORACLE优化器 ORACLE的优化器共有3种: a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性) 设置缺省的优化 ...

  6. (转)SQL 优化原则

    一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系 ...

  7. Oracle SQL优化一(常见方法)

    1.表访问方式优化: a)普通表优先“Index Lookup 索引扫描”,避免全表扫描 大多数场景下,通过“Index Lookup 索引扫描”要比“Full Table Scan (FTS) 全表 ...

  8. SQL 优化原则

    一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系 ...

  9. Oracle SQL优化器简介

    目录 一.Oracle的优化器 1.1 优化器简介 1.2 SQL执行过程 二.优化器优化方式 2.1 优化器的优化方式 2.2 基于规则的优化器 2.3 基于成本的优化器 三.优化器优化模式 3.1 ...

随机推荐

  1. lua 编译安装

    官网http://www.lua.org/download.html Building Lua is implemented in pure ANSI C and compiles unmodifie ...

  2. 寒假训练——搜索——C - Robot

    The Robot Moving Institute is using a robot in their local store to transport different items. Of co ...

  3. OLTP与OLAP的区别

    OLTP和OLAP的区别 联机事务处理OLTP(on-line transaction processing) 主要是执行基本日常的事务处理,比如数据库记录的增删查改.比如在银行的一笔交易记录,就是一 ...

  4. centos7下安装docker(18.3docker日志---logging driver---fluentd)

    前面我们学的ELK中用filebeat收集docker容器日志,利用的是dcoker默认的logging driver json-file,下面我们用fluentd来收集容器日志 Fluentd是一个 ...

  5. [Python] Python 100例

    题目1:有四个数字:1.2.3.4,能组成多少个互不相同且无重复数字的三位数?各是多少? 程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. #程序源 ...

  6. 第2章 Java并发机制的底层实现原理

    2.2 synchronized的实现原理与应用 当一个线程A执行字节码时遇到monitorenter指令时,会首先检查该指令关联的Object的对象头中的Mark Word状态. 2.2.1 如果是 ...

  7. pm2命令,端口查询,mongodb服务启动,nginx服务启动,n模块的使用,搭建nodejs服务器环境,搭建oracledb服务器环境 linux的环境搭建

    pm2命令 pm2 ls //查询pm2 启动的列表 pm2 start app.js //启动文件 pm2 restart app //重启项目 pm2 logs app //监控项目执行日志打印 ...

  8. 【js】鼠标跟随效果

    1.实现思想 ①鼠标跟随效果,发生在鼠标移动的时候,故需要使用onmousemove事件 ②当页面内容多于1屏时,就需要考虑滚动距离的问题 ③想实现鼠标跟随的效果需要: 元素的left位置 = 鼠标当 ...

  9. 1、原生jdbc连接oracle数据库简单介绍

    一.jbdc的常用API1.Connection:数据库的链接对象2.statement:数据库sql执行对象3.preparedStatment:sql的预编译处理对象,是statement子接口4 ...

  10. DVR登录绕过漏洞(CVE-2018-9995)

    ###漏洞描述 此漏洞允许攻击者通过修改“Cookie: uid=admin” 之后访问特定 DVR 的控制面板,返回此设备的明文管理员凭证. ###漏洞利用 1.利用代码 curl "ht ...