2011-09-21 132 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) 

:現在解釋替代查詢。