数据库性能调优技术─嵌套循环执行计划

2008-02-21 11:51:48.0     推荐:0    收藏:0    评论:0     来源:赛迪网

一、概述

单表执行计划是理解多表执行计划的基础。

两张表的连接有三种执行方式:1)嵌套循环连接;2)散列连接;3)归并连接。两张表连接时选择这三种中的哪一种呢?这取决于索引、以及连接的代价。在该系列的第三篇(本文)文章中讲解嵌套循环连接,第四篇文章中讲解散列连接,第五篇文章中讲解归并连接。在第六篇以后会分析IN子查询以及EXISTS子查询。

达梦数据库、oracle数据库、sql server数据库在数据库执行计划方面并无本质区别,因此上篇文章使用达梦数据库作为实例数据库进行分析,这篇文章我们选择oracle 10g作为实例数据库。

读完本文后,应该能够读懂这三个数据库的嵌套循环连接执行计划。

另外需要申明一点的是:因为oracle的源代码是不公开的,我这里描写的是根据执行计划、成本代价以及10053文件进行反推的结果,尽管这样,从大的方向上讲,不会出现问题,仅做抛砖引玉。

二、深入理解嵌套循环执行计划

Oracle数据库常用的显示执行计划的方式有两种:

(1) set autotrace on 命令;
(2) explain plan for 命令;

举例说明使用set autotrace命令:

  SQL> create table t1(c1 int,c2 int);
  Table created.
  SQL> create index it1c1 on t1(c1);
  Index created.
  SQL> insert into t1 values(1,1);
  1 row created.
  SQL> insert into t1 values(2,2);
  1 row created.
  SQL> commit;
  Commit complete.
  SQL> set autotrace on explain;
  SQL> select c1 from t1 where c1=1;

我们可以看到,执行了“set autotrace on explain;”语句之后,接下来的查询、插入、更新、删除语句就会显示执行计划,直到执行“set autotrace off;”语句。如果是设置了“set autotrace on;”,除了会显示执行计划之外,还会显示一些有用的统计信息。本系列文章不涉及查询代价的评估分析。

我们从上一段代码中,我们发现在显示“select c1 from t1 where c1=1;”执行计划之前显示了该执行语句的查询结果。这说明:显示执行计划之前就真正地将该查询语句执行了一遍。这样会带来一个不好后果,假设我们现在有一条语句,执行的时间需要半个小时,即使我们仅仅需要知道该语句的执行计划,此种情况下,我们必须等待半个小时。因此,如果查询的性能很慢,我们可以选择选择使用explain plan for命令。

举例说明explain plan for命令:

SQL> explain plan for select c1 from t1 where c1=1;
Explained.
SQL> select * from table(DBMS_XPLAN.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------
Plan hash value: 2624316456
--------------------------------------------------------------------------
| Id  | Operation        | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       |     1 |    13 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IT1C1 |     1 |    13 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
PLAN_TABLE_OUTPUT
-------------------------------------------------------------
   1 - access("C1"=1)
Note
-----
   - dynamic sampling used for this statement
17 rows selected.
SQL>

使用“explain plan for 查询语句;”生成执行计划,然后使用“select * from table(DBMS_XPLAN.display);”语句显示执行计划。

下面的内容,将通过一些例子来理解嵌套理解执行计划:

1.不带索引的嵌套连接的执行计划该如何理解?

构造处测试场景:

查询语句为:

select /*+ USE_NL(t2) */ c1,c2 from t1 inner join t2 on c1=d2;

该语句中“/*+ USE_NL(t2) */”是我们常说的hint提示,这里的USE_NL告诉优化程序使用嵌套连接对表进行连接,t2为内部表。此查询语句的执行计划为:

Execution Plan
----------------------------------------------------------
0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=4 Card=2 Bytes=78)
1    0   NESTED LOOPS (Cost=4 Card=2 Bytes=78)
2    1     TABLE ACCESS (FULL) OF 'T1' (TABLE) (Cost=2 Card=2 Bytes
=52)

3    1     TABLE ACCESS (FULL) OF 'T2' (TABLE) (Cost=1 Card=1 Bytes
=13)
[第1页]   [第2页]   [第3页]   [下一页]
您可以针对本文进行:[评论]  [收藏]  [推荐]  
  • 共有0条评论  点击查看更多评论
  • 网友评论仅供网友表达个人看法,并不表明e800同意其观点或证实其描述
我想发表评论:
用户名密码
  • 匿名发表
    验证码: