select /*+ORDERED USE_NL(EMP)*/ empno,DNAME from emp, dept
where emp.deptno = dept.deptno;
为什么执行计划走到不是NL而是HASH JOIN
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=82 Bytes=3936)
1 0 HASH JOIN (Cost=5 Card=82 Bytes=3936)
2 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=82 Bytes=2132)
3 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=82 Bytes=1804)而且,网上很多例子和我运行效果不一样,是什么原因?例如下面的
网络上的HASH连接的例子:
SQL> explain plan for
select /*+ use_hash(emp) */ empno
from emp, dept
where emp.deptno = dept.deptno;
Query Plan
SELECT STATEMENT [CHOOSE] Cost=33 A)
HASH JOIN
TABLE ACCESS FULL DEPT
TABLE ACCESS FULL EMP我运行的结果:Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=82 Bytes=3198)
1 0 NESTED LOOPS (Cost=2 Card=82 Bytes=3198)
2 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=82 Bytes=2132)
3 1 INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)注明:我的环境是Connected to Oracle9i Enterprise Edition Release 9.2.0.1.0
努力学习语句优化中,给点指点....
where emp.deptno = dept.deptno;
为什么执行计划走到不是NL而是HASH JOIN
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=82 Bytes=3936)
1 0 HASH JOIN (Cost=5 Card=82 Bytes=3936)
2 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=82 Bytes=2132)
3 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=82 Bytes=1804)而且,网上很多例子和我运行效果不一样,是什么原因?例如下面的
网络上的HASH连接的例子:
SQL> explain plan for
select /*+ use_hash(emp) */ empno
from emp, dept
where emp.deptno = dept.deptno;
Query Plan
SELECT STATEMENT [CHOOSE] Cost=33 A)
HASH JOIN
TABLE ACCESS FULL DEPT
TABLE ACCESS FULL EMP我运行的结果:Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=82 Bytes=3198)
1 0 NESTED LOOPS (Cost=2 Card=82 Bytes=3198)
2 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=82 Bytes=2132)
3 1 INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)注明:我的环境是Connected to Oracle9i Enterprise Edition Release 9.2.0.1.0
努力学习语句优化中,给点指点....
解决方案 »
- 急急!!!!!SQL Plus查询的结果集怎样设置回横向显示
- 请教:按用户数购买Oracle在实际应用中如果超出该用户数是何结果
- 一个有点诡异的问题,执行impdp命令在导入某些临时表时出现ORA-00936错误
- 请问怎么插入timestamp类型?
- ORACLE与IP-SAN
- Oracle存储过程调用问题。
- 在oracle中动态sql语句如何执行?
- 如何手动删除OC4J
- 很困难select 语句问题?
- 求救:关于ORA-12545的解决方法
- 两台AIX服务器做完HA以后,用plsqlmanager客户端连接数据库经常超时?
- 紧急求救!!:server was unable to process request,为什么??
select /*+ use_hash(emp,dept) */ empno
from emp, dept
where emp.deptno = dept.deptno;
得到的执行计划就是HASH JOIN了
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=82 Bytes=3198 )
1 0 HASH JOIN (Cost=5 Card=82 Bytes=3198)
2 1 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=82 Bytes=2132)
3 1 TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=82 Bytes=1066 )
select /*+ORDERED USE_NL(EMP,DEPT)*/ empno,DNAME from emp, dept
where emp.deptno = dept.deptno;
where emp.deptno = dept.deptno;
这个的我知道的,可是,应该只是EMP作为内部表啊,而DEPT的外部表才对,都把它放到里面,
之前也认真查过此种方法,转自如下
USE_NL(),先看看oracle doc怎么说:
In this statement, the USE_NL hint explicitly chooses a nested loops join with the customers table as the inner table:
SELECT /*+ ORDERED USE_NL(customers) to get first row faster */
accounts.balance, customers.last_name, customers.first_name
FROM accounts, customers
WHERE accounts.customer_id = customers.customer_id;
customers 作为inner table,也就是说作为被驱动表。驱动表称为outer table。
也就是说use_nl如果只带了一个表名作为参数,则该表为被驱动表。
如果带了2个以上的参数,oracle 并没有指出 use_nl(a b) 中 哪个是驱动表,所以常使用 ordered 或者 full() 或者 index() 来强化我们的目标
而使用
select /*+ORDERED USE_NL(dept)*/ empno,DNAME from emp, dept
where emp.deptno = dept.deptno;时执行计划显示正常,
所以用EMP作为驱动表时候执行计划用HJ才奇怪,我已经强制使用了NL提示了啊,应该无条件按照NL方式执行才对啊,......疑问
where emp.deptno = dept.deptno;
EMP的DEPTNO是索引,仍然走hash join,虽然很想知道为什么,但是记住就可以了,这的优化规则而已..