2011-09-21 35 views
0

当我们在Oracle中的两个表之间创建连接时,在一个或两个表上有一些额外的过滤条件时,oracle会先加入表,然后过滤或将过滤条件先加入。数据库(oracle)如何连接处理过滤条件

或者用通俗的话说,这些2的是一个更好的查询

说,我们有2台员工和部门,我希望员工全体员工+部门详细其中员工工资是刨丝器50000

查询1: 从雇员e,部门d选择e.name,d.name,其中e.dept_id = d.id和e.salary> 50000;

查询2: 从(select * from employee where salary> 50000)select e.name,d.name e,department d where e.dept_id = d.id;

回答

5

通常它会尽可能先过滤。从解释计划,你可以看到在过滤完成,并在那里完成,例如,创建一些表格和数据连接:

create table employees (id integer, dept_id integer, salary number); 

create table dept (id integer, dept_name varchar2(10)); 

insert into dept values (1, 'IT'); 

insert into dept values (2, 'HR'); 

insert into employees 
select level, mod(level, 2) + 1, level * 1000 
from dual connect by level <= 100; 

create index employee_uk1 on employees (id); 

create index dept_uk1 on dept (id); 

exec dbms_stats.gather_table_stats(user, 'DEPT'); 

现在,如果我解释这两个你提供,你会查询发现Oracle将每个查询转换为幕后的相同计划(它并不总是执行您认为它的操作 - Oracle拥有'重写'查询的许可,并且它执行了很多操作):

explain plan for 
select e.*, d.* 
from employees e, dept d 
where e.dept_id = d.id 
and e.salary > 5000; 

select * from table(dbms_xplan.display()); 

    ------------------------------------------------------------------------------------------ 
| Id | Operation     | Name  | Rows | Bytes | Cost (%CPU)| Time  | 
------------------------------------------------------------------------------------------ 
| 0 | SELECT STATEMENT    |   | 96 | 1536 |  6 (17)| 00:00:01 | 
| 1 | MERGE JOIN     |   | 96 | 1536 |  6 (17)| 00:00:01 | 
| 2 | TABLE ACCESS BY INDEX ROWID| DEPT  |  2 | 12 |  2 (0)| 00:00:01 | 
| 3 | INDEX FULL SCAN   | DEPT_UK1 |  2 |  |  1 (0)| 00:00:01 | 
|* 4 | SORT JOIN     |   | 96 | 960 |  4 (25)| 00:00:01 | 
|* 5 | TABLE ACCESS FULL   | EMPLOYEES | 96 | 960 |  3 (0)| 00:00:01 | 

4 - access("E"."DEPT_ID"="D"."ID") 
    filter("E"."DEPT_ID"="D"."ID") 
5 - filter("E"."SALARY">5000) 

注意应用于查询的过滤器操作。一旦你学会如何得到解释的计划以及如何阅读它们,你通常可以工作了甲骨文在做,因为它执行查询

explain plan for 
select e.*, d.* 
from (select * from employees where salary > 5000) e, dept d 
where e.dept_id = d.id; 

------------------------------------------------------------------------------------------ 
| Id | Operation     | Name  | Rows | Bytes | Cost (%CPU)| Time  | 
------------------------------------------------------------------------------------------ 
| 0 | SELECT STATEMENT    |   | 96 | 1536 |  6 (17)| 00:00:01 | 
| 1 | MERGE JOIN     |   | 96 | 1536 |  6 (17)| 00:00:01 | 
| 2 | TABLE ACCESS BY INDEX ROWID| DEPT  |  2 | 12 |  2 (0)| 00:00:01 | 
| 3 | INDEX FULL SCAN   | DEPT_UK1 |  2 |  |  1 (0)| 00:00:01 | 
|* 4 | SORT JOIN     |   | 96 | 960 |  4 (25)| 00:00:01 | 
|* 5 | TABLE ACCESS FULL   | EMPLOYEES | 96 | 960 |  3 (0)| 00:00:01 |  

4 - access("EMPLOYEES"."DEPT_ID"="D"."ID") 
    filter("EMPLOYEES"."DEPT_ID"="D"."ID") 
5 - filter("SALARY">5000) 

:现在解释替代查询。