Oracle优化之联结与子查询
2014-04-12 07:28
190 查看
概述: 无论联结的逻辑分类是什么,Oracle在处理时有三种联结算法:嵌套循环联结(nested loops join)、排序合并联结(sort-merge join)和散列联结(hash join)。
1 . 嵌套循环联结
先来看看嵌套循环联结是如何工作的。如下图:
—— 总结, 对外表中的每一条记录,我们都在内表中查找匹配的记录。因为内表查找必须发生多次,它必须废除高效:通常这意味着索引查 找必须支持 内表。 如果没有对内表的索引,那么可能要对外表的每一条记录扫描内表一次;这就是经常说的糟糕的嵌套表扫描,随着表大 小的增长,它可能导致开销和执行时间呈指数级的增长。
由于嵌套表扫描很糟糕,一般情况下,只有内表上有索引时优化器才会选择嵌套循环操作。即使内表上有索引,如果要访问内表的全部 或者大部分数据,嵌套循环的过程还是没有排序合并或散列联结高效。
2 . 排序合并联结
还是来看看排序合并联结的工作机制吧:
——总结,排序合并联结适用于需要包含访问表中的大部分数据或者内标没有声音访问可用的联结。
3 . 散列联结
老样子, 先来看看散列联结的工作机制:
——总结,一般情况下,在散列联结和排序合并联结都可以使用的条件下,散列联结比排序合并联结更加高效,而且在一张表的大部分数 据被访问的情况下,散列联结也比嵌套循环联结更加高效。
4 . 选择正确的联结方法
4.1 排序合并联结/散列联结 与嵌套循环联结的对比
A . 对吞吐量的需求和响应时间的需求的比较。 嵌套循环联结通常可以提供更快速的相应时间, 而散列/排序合并联结通常会提供更大的吞 吐 量。
B . 参与联结的记录在表中的比例。 被处理的记录的子集越大,排序合并或者散列联结就可能越快。
C . 是否有索引可用来支持联结。嵌套循环联结的方法通常指在索引可用于联结表时才有效。
——当联结涉及的记录只占表中相对较小的比例并且有索引支持的时候,嵌套循环联结方法较为合适。而当表的大部分数据参与联结或者没 有合适的索引时,排序合并和散列联结则更加合适。
——我们可以使用提示来促使优化器做出选择,如:
SQL> EXPLAIN PLAN FOR
SELECT /*+ ORDERED USE_MERGE(s) */
MAX(salary)
FROM staff s JOIN dep d USING (depid) ;
4.2 优化嵌套循环联结
优化嵌套循环联结需要确保内表的联结列上存在高选择性的索引,性能最该的嵌套循环联结是在联结查询中用到的所有列存在于一个组合 索引中。
4.3 优化排序合并联结与散列联结
散列联结和排序合并联结对内存都很敏感。要达到最优的性能,排序合并需要更多的内存,当它的操作不能完全在内存中完成时,性能会急 剧下降。
4.4 避免联结
为了避免联结,提供以下建议(方法):
A . 在一张表中维护另一张表的反范式化的数据。
B . 将表存储在索引聚簇(INDEX CLUSTER)中,是两张表中有共同键的记录存储在同一个块中。
C . 创建基于两个表联结的位图联结索引(有待研究)。
D . 创建物化视图,将联结操作的结果存储到单独的段中。
5 . 反范式化
避免联结开销是反范式化的典型的原因之一。 推荐使用触发器自动实现反范式化。
6 . 联结顺序
我想,很多人都很想知道:你前面说的都是两张表,那多张表JOIN怎么办呢? 下面就说说Oracle的联结顺序。如下:
——Oracle一次联结两张表;每个联结都会产生一个结果集,这个结果集又成为后续联结的输入。
7 . 反联结子查询
反联结查询是一种返回在一张表中和另一张表中的某些记录簿匹配的记录的查询。
——除非联结键被定义为非空,否则不要在反联结中使用 NOT IN。如果锁包含的列是可以为空的,使用NOT EXISTS 反联结替代。要重点了 解NOT IN与NOT EXISTS,以及NOT IN 查询空值的时候会有扫描结果?
1 . 嵌套循环联结
先来看看嵌套循环联结是如何工作的。如下图:
—— 总结, 对外表中的每一条记录,我们都在内表中查找匹配的记录。因为内表查找必须发生多次,它必须废除高效:通常这意味着索引查 找必须支持 内表。 如果没有对内表的索引,那么可能要对外表的每一条记录扫描内表一次;这就是经常说的糟糕的嵌套表扫描,随着表大 小的增长,它可能导致开销和执行时间呈指数级的增长。
由于嵌套表扫描很糟糕,一般情况下,只有内表上有索引时优化器才会选择嵌套循环操作。即使内表上有索引,如果要访问内表的全部 或者大部分数据,嵌套循环的过程还是没有排序合并或散列联结高效。
2 . 排序合并联结
还是来看看排序合并联结的工作机制吧:
——总结,排序合并联结适用于需要包含访问表中的大部分数据或者内标没有声音访问可用的联结。
3 . 散列联结
老样子, 先来看看散列联结的工作机制:
——总结,一般情况下,在散列联结和排序合并联结都可以使用的条件下,散列联结比排序合并联结更加高效,而且在一张表的大部分数 据被访问的情况下,散列联结也比嵌套循环联结更加高效。
4 . 选择正确的联结方法
4.1 排序合并联结/散列联结 与嵌套循环联结的对比
A . 对吞吐量的需求和响应时间的需求的比较。 嵌套循环联结通常可以提供更快速的相应时间, 而散列/排序合并联结通常会提供更大的吞 吐 量。
B . 参与联结的记录在表中的比例。 被处理的记录的子集越大,排序合并或者散列联结就可能越快。
C . 是否有索引可用来支持联结。嵌套循环联结的方法通常指在索引可用于联结表时才有效。
——当联结涉及的记录只占表中相对较小的比例并且有索引支持的时候,嵌套循环联结方法较为合适。而当表的大部分数据参与联结或者没 有合适的索引时,排序合并和散列联结则更加合适。
——我们可以使用提示来促使优化器做出选择,如:
SQL> EXPLAIN PLAN FOR
SELECT /*+ ORDERED USE_MERGE(s) */
MAX(salary)
FROM staff s JOIN dep d USING (depid) ;
4.2 优化嵌套循环联结
优化嵌套循环联结需要确保内表的联结列上存在高选择性的索引,性能最该的嵌套循环联结是在联结查询中用到的所有列存在于一个组合 索引中。
4.3 优化排序合并联结与散列联结
散列联结和排序合并联结对内存都很敏感。要达到最优的性能,排序合并需要更多的内存,当它的操作不能完全在内存中完成时,性能会急 剧下降。
4.4 避免联结
为了避免联结,提供以下建议(方法):
A . 在一张表中维护另一张表的反范式化的数据。
B . 将表存储在索引聚簇(INDEX CLUSTER)中,是两张表中有共同键的记录存储在同一个块中。
C . 创建基于两个表联结的位图联结索引(有待研究)。
D . 创建物化视图,将联结操作的结果存储到单独的段中。
5 . 反范式化
避免联结开销是反范式化的典型的原因之一。 推荐使用触发器自动实现反范式化。
6 . 联结顺序
我想,很多人都很想知道:你前面说的都是两张表,那多张表JOIN怎么办呢? 下面就说说Oracle的联结顺序。如下:
——Oracle一次联结两张表;每个联结都会产生一个结果集,这个结果集又成为后续联结的输入。
7 . 反联结子查询
反联结查询是一种返回在一张表中和另一张表中的某些记录簿匹配的记录的查询。
——除非联结键被定义为非空,否则不要在反联结中使用 NOT IN。如果锁包含的列是可以为空的,使用NOT EXISTS 反联结替代。要重点了 解NOT IN与NOT EXISTS,以及NOT IN 查询空值的时候会有扫描结果?
相关文章推荐
- Oracle优化——三种联结方法
- Oracle优化——星型联结转换(star_transformation_enabled)
- Oracle语句优化53个规则详解
- Oracle优化:避免全表扫描
- oracle优化几点注意
- 【Oracle优化笔记】哈希连接(HASH JOIN)详解
- Oracle的优化器
- ORACLE SQL优化 续
- 索引、物化视图-oracle 性能调优之 数据访问路径优化-by小雨
- ORACLE SQL性能优化二
- Oracle大数据SQL语句优化
- 浅谈ORACLE SQL语句优化经验
- Oracle sql语句优化53个规则详解(一)(www.jiedichina.com)
- [翻译]Oracle中的增强子查询优化[转载]
- Oracle SQL 'or' 的优化,最近的案例一则。
- Oracle会话及连接数优化
- oracle-sql优化总结
- oracle查询性能优化
- 在使用 ST_Geometry 空间索引时优化 Oracle 查询性能和存储
- 【Oracle_性能优化】Oracle SQL性能优化【20140612】