1.笛卡儿积 merge join cartesion
SQL> select ename,dname from emp,dept;
已选择56行。
执行计划
----------------------------------------------------------
Plan hash value: 2034389985
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 56 | 896 | 10 (0)| 00:00:01 |
| 1 | MERGE JOIN CARTESIAN| | 56 | 896 | 10 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL | DEPT | 4 | 36 | 3 (0)| 00:00:01 |
| 3 | BUFFER SORT | | 14 | 98 | 7 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | EMP | 14 | 98 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------
这个笛卡儿积的产生是我们设定的是因为没有关联条件
真实的系统中
1.优化器算rows算错了的时候容易引起笛卡尔积
2.没有关联条件
禁用笛卡儿积的hint/*+ opt_param('_optimizer_mjc_enabled','false')*/
2.外连接
1.a left join on b 如果a和b之间是嵌套循环关系,驱动表只能是a
2.如果a和b是hash join
SQL> select ename,dname from emp left join dept on emp.deptno=dept.deptno;
已选择14行。
执行计划
----------------------------------------------------------
Plan hash value: 3387915970
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 588 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN OUTER | | 14 | 588 | 7 (15)| 00:00:01 |
| 2 | TABLE ACCESS FULL| EMP | 14 | 280 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| DEPT | 4 | 88 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
leading没有用,不能改变谁是驱动表
SQL> select /*+use_hash(emp,dept) leading(dept) */ ename,dname from emp left join dept on emp.deptno=dept.deptno;
已选择14行。
执行计划
----------------------------------------------------------
Plan hash value: 3387915970
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 588 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN OUTER | | 14 | 588 | 7 (15)| 00:00:01 |
| 2 | TABLE ACCESS FULL| EMP | 14 | 280 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| DEPT | 4 | 88 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
要想改变只能用swap_join_inputs() 这个是专用来改hash join的驱动表的
SQL> select /*+use_hash(emp,dept) swap_join_inputs(dept) */ ename,dname from emp left join dept on emp.deptno=dept.deptno;
已选择14行。
执行计划
----------------------------------------------------------
Plan hash value: 4261033907
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 588 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN RIGHT OUTER| | 14 | 588 | 7 (15)| 00:00:01 |
| 2 | TABLE ACCESS FULL | DEPT | 4 | 88 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | EMP | 14 | 280 | 3 (0)| 00:00:01 |
------------------------------------------------------------------------------
3.标量子查询
1.select子句中有查询语句就是标量子查询,尽量不要使用标量子查询除了在分页语句中
2.必须使用的时候要在被驱动表的连接列上创建索引也就是在标量子查询的表的筛选列上建索引。
3.能改写的时候改成外连接。
4.在sql中有自定义函数,跟标量子查询一样