`
s海若
  • 浏览: 18056 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

从查询计划看Oracle连接查询性能误解

阅读更多
内连接:
SQL/86
select *
from products p, product_types pt
where p.product_type_id = pt.product_type_id;

SQL/92
select *
from products p
inner join product_types using(product_type_id);

左外连接:
SQL/86
select *
from products p, product_types pt
where p.product_type_id = pt.product_type_id(+);

SQL/92
select *
from products
left outer join product_types using(product_type_id);

右外连接:
SQL/86
select *
from products p, product_types pt
where p.product_type_id (+) = pt.product_type_id;

SQL/92
select *
from products p
right outer join product_types pt using(product_type_id);

全外连接:
SQL/86
无对应语法
SQL/92
select *
from products p
full outer join product_types pt using(product_type_id);

笛卡尔积:
SQL/86
select *
from products p, product_types pt

SQL/92
select *
from products p
cross join product_types


误解一:SQL/86语句比SQL/92快
以内连接为例,
SQL/86的Plan:
-------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                  |    11 |   605 |     6  (17)| 00:00:01 |
|   1 |  MERGE JOIN                  |                  |    11 |   605 |     6  (17)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| PRODUCT_TYPES    |     5 |    40 |     2   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN           | PRODUCT_TYPES_PK |     5 |       |     1   (0)| 00:00:01 |
|*  4 |   SORT JOIN                  |                  |    11 |   517 |     4  (25)| 00:00:01 |
|*  5 |    TABLE ACCESS FULL         | PRODUCTS         |    11 |   517 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
SQL/92的Plan:
-------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                  |    11 |   605 |     6  (17)| 00:00:01 |
|   1 |  MERGE JOIN                  |                  |    11 |   605 |     6  (17)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| PRODUCT_TYPES    |     5 |    40 |     2   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN           | PRODUCT_TYPES_PK |     5 |       |     1   (0)| 00:00:01 |
|*  4 |   SORT JOIN                  |                  |    11 |   517 |     4  (25)| 00:00:01 |
|*  5 |    TABLE ACCESS FULL         | PRODUCTS         |    11 |   517 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
是的,两者的结果是一样的。所以SQL/86的效率其实与SQL/92的等价语句是一样的,只是形式的不同,在后台它们执行的是相同的操作。曾经碰到过有位经验丰富的前辈在做SQL调优的时候就搬出了SQL/86的语法来替代原来有的Join操作,当时还十分钦佩,现在看来只是个习惯问题,并不能带来实质上性能的提升。其他的连接也可以得出同样的结论。

误解二:left join 和right join是连接不同方向上的等价语句。
left join的Plan:
------------------------------------------------------------------------------------
| Id  | Operation          | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |               |    12 |   660 |     7  (15)| 00:00:01 |
|*  1 |  HASH JOIN OUTER   |               |    12 |   660 |     7  (15)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| PRODUCTS      |    12 |   564 |     3   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL| PRODUCT_TYPES |     5 |    40 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------
right join的Plan:
-------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                  |    11 |   605 |     6  (17)| 00:00:01 |
|   1 |  MERGE JOIN OUTER            |                  |    11 |   605 |     6  (17)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| PRODUCT_TYPES    |     5 |    40 |     2   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN           | PRODUCT_TYPES_PK |     5 |       |     1   (0)| 00:00:01 |
|*  4 |   SORT JOIN                  |                  |    11 |   517 |     4  (25)| 00:00:01 |
|*  5 |    TABLE ACCESS FULL         | PRODUCTS         |    11 |   517 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
由此可见,left join 只要扫描两个表,然后使用hash join就可以完成,而right join则要执行与inner join类似的操作。所以在同等的情况下,使用left join 总是要比right join好。

误解三:全连接比笛卡尔积快。
显然全连接的记录数量要比笛卡尔积少的多,但是记录少并不代表一定就快。
full join的Plan:
---------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                  |    13 |  1170 |    13  (16)| 00:00:01 |
|   1 |  VIEW                          |                  |    13 |  1170 |    13  (16)| 00:00:01 |
|   2 |   UNION-ALL                    |                  |       |       |            |          |
|*  3 |    HASH JOIN OUTER             |                  |    12 |   660 |     7  (15)| 00:00:01 |
|   4 |     TABLE ACCESS FULL          | PRODUCTS         |    12 |   564 |     3   (0)| 00:00:01 |
|   5 |     TABLE ACCESS FULL          | PRODUCT_TYPES    |     5 |    40 |     3   (0)| 00:00:01 |
|   6 |    MERGE JOIN ANTI             |                  |     1 |    11 |     6  (17)| 00:00:01 |
|   7 |     TABLE ACCESS BY INDEX ROWID| PRODUCT_TYPES    |     5 |    40 |     2   (0)| 00:00:01 |
|   8 |      INDEX FULL SCAN           | PRODUCT_TYPES_PK |     5 |       |     1   (0)| 00:00:01 |
|*  9 |     SORT UNIQUE                |                  |    11 |    33 |     4  (25)| 00:00:01 |
|* 10 |      TABLE ACCESS FULL         | PRODUCTS         |    11 |    33 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------
cross join的Plan:
--------------------------------------------------------------------------------------
| Id  | Operation            | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |               |    60 |  3300 |    10   (0)| 00:00:01 |
|   1 |  MERGE JOIN CARTESIAN|               |    60 |  3300 |    10   (0)| 00:00:01 |
|   2 |   TABLE ACCESS FULL  | PRODUCT_TYPES |     5 |    40 |     3   (0)| 00:00:01 |
|   3 |   BUFFER SORT        |               |    12 |   564 |     7   (0)| 00:00:01 |
|   4 |    TABLE ACCESS FULL | PRODUCTS      |    12 |   564 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
可以看到事实上查询笛卡尔积要比查询全外连接快得多。


分享到:
评论

相关推荐

    Oracle数据库高级技术交流计划-性能调优.ppt

    在Oracle数据库高级技术交流计划中,重点讨论了性能调优的原理、交易系统与查询统计系统的差异分析,以及SQL性能优化等多个方面。 首先,性能优化原理强调了对常见误解的澄清。许多人认为调优只是系统参数的调整,...

    Oracle_Errors(oracle错误信息)解释

    `oracle错误中文解释.txt` 文件可能是对Oracle错误的中文翻译或解释,这对于中文使用者来说非常方便,因为官方文档通常以英文为主,中文解释可以帮助用户更直观地理解错误信息,避免因语言障碍导致的误解。...

    Oracle函数与查询.pptx

    在进行复杂查询时,了解如何有效使用索引、连接方法和子查询优化性能至关重要。Oracle提供了EXPLAIN PLAN工具帮助分析查询执行计划。 8. **查询构造**: 除了基本的SELECT、FROM、WHERE子句,Oracle还支持子查询...

    oracle 学习笔记

    4. 子查询、连接和集合的总结涉及如何根据查询需求选择合适的查询方式。 十五、排名分页问题 1. Rownum是Oracle数据库中用于表示查询结果集中行号的一个伪列。 2. Rownum在SQL中使用时有一些特殊的行为,特别是在带...

    ORACLE 编程架构

    - **提高应用性能**:提供了提高应用程序性能的方法,如合理使用索引和查询优化技巧。 - **DBA与开发人员的关系**:强调了DBA(数据库管理员)与开发人员之间协作的重要性,以确保系统的稳定性和性能。 ##### 1.4 小...

    oracle 10g 学习手册

    6. **性能优化**:Oracle的性能优化工具,如SQL*Plus、 tkprof 和AWR(Automatic Workload Repository)报告,可以帮助分析和改进查询性能。了解如何解读和利用这些工具的数据,是提升系统性能的关键。 7. **安全...

    如何设计高效合理的SQL查询语句

    一个好的查询计划可以显著提升程序性能。查询计划是用户提交的一系列SQL语句的集合,而查询规划则是经过优化处理后生成的语句集合。DBMS处理查询计划的过程大致如下: 1. 首先,DBMS会对提交的SQL语句进行词法和...

    Oracle Index Internals.pdf

    - **Oracle索引结构概述**:文档首先提供了Oracle索引结构的概述,涵盖了B树索引、反转索引、基于函数的索引、位图索引、位图连接索引以及分区索引等。 - **Oracle索引误区总结**:列出了一些常见的误解,例如索引会...

    ojdbc6.jar

    在Oracle的上下文中,这可能是指一个包含多种JDBC驱动(比如除了Oracle之外的其他数据库的驱动)的集合包,或者是在某些情况下,是用户对"ojdbc.jar"的一个误解或误写。 使用这些JDBC驱动,开发者可以编写Java代码...

    数据库导出文档工具.zip

    MySQL是一种开源、免费的关系型数据库管理系统,被广泛应用于互联网应用,其简单易用、性能优异的特点深受开发者喜爱。Oracle则是一款企业级的商业数据库系统,提供高度可靠性和安全性,常用于大型企业或高并发的...

    SQL数据库字典生成器(带源码)

    生成过程可能包括连接数据库、查询表结构、获取字段信息、索引和约束等,并将这些信息整理成Excel表格。 3. **源码分析**: - `DbDictionaryBuilder`:这个可能是程序的主要类,负责整个字典生成的流程控制。它...

    数据库设计规范v1.0

    使用专业的数据库设计工具,如Oracle SQL Developer或ER/Studio,辅助进行数据库建模、逆向工程、性能分析等工作,提高设计效率和准确性。 综上所述,"数据库设计规范v1.0"主要涵盖了从数据库环境配置到逻辑设计的...

    psql 13 64位

    在压缩包子文件的文件名称列表中,我们看到"plsqldev1300x64.msi",这个文件名可能引发一些误解,因为"plsqldev"通常指的是Oracle的PL/SQL Developer,这是一个用于Oracle数据库的集成开发环境,而非PostgreSQL的...

    RAC与ASM最佳实践

    ### RAC与ASM最佳实践详解 #### 一、引言 在现代企业的IT环境中,确保高可用...通过遵循上述规划、实施和运行维护的最佳实践,企业可以充分利用RAC和ASM的优势,实现高可用性、高性能和易于管理的Oracle数据库环境。

    ionic的学习材料挺不错的

    根据提供的信息来看,这里似乎存在一个误解,因为给出的文件实际上是关于ToughRADIUS操作手册的内容,而不是关于Ionic的学习资料。然而,为了满足任务需求,我们依然可以从这些信息中提炼出一些与IT相关的知识点,...

    找到数据库开发者的捷径

    在遵循第三范式的同时,也要注意过度规范化可能会导致查询性能的下降,因此开发者需要在规范化与反规范化之间找到平衡点,并根据实际的应用需求灵活调整设计策略。 最后,数据库设计应避免包含过多的应用逻辑,以...

    阿里云服务器实例web工程

    在本项目中,"web_exception_project"虽然在名称上可能让人误解为异常处理相关的项目,实际上它是一个包含了数据库连接功能的Web服务实例。这个项目的核心是利用阿里云的计算资源来提供稳定、高效且安全的Web服务。 ...

Global site tag (gtag.js) - Google Analytics