统计每个部门员工总工资。
原SQL:
select d.department_id,
d.department_name,
nvl((select sum(e.salary)
from employees e
where e.department_id = d.department_id),
0) sum_amt
from departments d;
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------
Plan hash value: 1383367578
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 27 | 432 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 7 | | |
| 2 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 10 | 70 | 2 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX | 10 | | 1 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | DEPARTMENTS | 27 | 432 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("E"."DEPARTMENT_ID"=:B1)
改写SQL 将子查询结果作为内联视图,与外部表进行关联
select d.department_id,
d.department_name,
sum_amt from departments d left outer join (
select department_id,sum(e.salary) sum_amt
from employees e
group by department_id)e on(d.department_id=e.department_id);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------
Plan hash value: 3662601325
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 27 | 1134 | 7 (29)| 00:00:01 |
| 1 | MERGE JOIN OUTER | | 27 | 1134 | 7 (29)| 00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID| DEPARTMENTS | 27 | 432 | 2 (0)| 00:00:01 |
| 3 | INDEX FULL SCAN | DEPT_ID_PK | 27 | | 1 (0)| 00:00:01 |
|* 4 | SORT JOIN | | 11 | 286 | 5 (40)| 00:00:01 |
| 5 | VIEW | | 11 | 286 | 4 (25)| 00:00:01 |
| 6 | HASH GROUP BY | | 11 | 77 | 4 (25)| 00:00:01 |
| 7 | TABLE ACCESS FULL | EMPLOYEES | 107 | 749 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("D"."DEPARTMENT_ID"="E"."DEPARTMENT_ID"(+))
filter("D"."DEPARTMENT_ID"="E"."DEPARTMENT_ID"(+))
已选择20行。
根据以上方式改写以下SQL:
select first_name,
department_name,
nvl((select min_salary
from jobs
where employees.job_id = jobs.job_id
and jobs.job_title = 'President'),
0) pre_min_sal,
nvl((select min_salary
from jobs
where employees.job_id = jobs.job_id
and jobs.job_title = 'Administration Vice President'),
0) avp_sal,
nvl((select min_salary
from jobs
where employees.job_id = jobs.job_id
and jobs.job_title = 'Administration Assistant'),
0) aa_sal,
nvl((select max_salary
from jobs
where employees.job_id = jobs.job_id
and jobs.job_title = 'Finance Manager'),
0) fm_sal,
nvl((select max_salary
from jobs
where employees.job_id = jobs.job_id
and jobs.job_title = 'Public Accountant'),
0) pa_sal,
nvl((select max_salary
from jobs
where employees.job_id = jobs.job_id
and jobs.job_title = 'Purchasing Manager'),
0) pm_sal,
nvl((select city
from locations
where locations.location_id = departments.location_id),
0) city
from employees
inner join departments
on (employees.department_id = departments.department_id);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------
Plan hash value: 1446905011
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 106 | 4028 | 6 (17)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID | JOBS | 1 | 31 | 1 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | JOB_ID_PK | 1 | | 0 (0)| 00:00:01 |
|* 3 | TABLE ACCESS BY INDEX ROWID | JOBS | 1 | 31 | 1 (0)| 00:00:01 |
|* 4 | INDEX UNIQUE SCAN | JOB_ID_PK | 1 | | 0 (0)| 00:00:01 |
|* 5 | TABLE ACCESS BY INDEX ROWID | JOBS | 1 | 31 | 1 (0)| 00:00:01 |
|* 6 | INDEX UNIQUE SCAN | JOB_ID_PK | 1 | | 0 (0)| 00:00:01 |
|* 7 | TABLE ACCESS BY INDEX ROWID | JOBS | 1 | 31 | 1 (0)| 00:00:01 |
|* 8 | INDEX UNIQUE SCAN | JOB_ID_PK | 1 | | 0 (0)| 00:00:01 |
|* 9 | TABLE ACCESS BY INDEX ROWID | JOBS | 1 | 31 | 1 (0)| 00:00:01 |
|* 10 | INDEX UNIQUE SCAN | JOB_ID_PK | 1 | | 0 (0)| 00:00:01 |
|* 11 | TABLE ACCESS BY INDEX ROWID | JOBS | 1 | 31 | 1 (0)| 00:00:01 |
|* 12 | INDEX UNIQUE SCAN | JOB_ID_PK | 1 | | 0 (0)| 00:00:01 |
| 13 | TABLE ACCESS BY INDEX ROWID | LOCATIONS | 1 | 12 | 1 (0)| 00:00:01 |
|* 14 | INDEX UNIQUE SCAN | LOC_ID_PK | 1 | | 0 (0)| 00:00:01 |
| 15 | MERGE JOIN | | 106 | 4028 | 6 (17)| 00:00:01 |
| 16 | TABLE ACCESS BY INDEX ROWID| DEPARTMENTS | 27 | 513 | 2 (0)| 00:00:01 |
| 17 | INDEX FULL SCAN | DEPT_ID_PK | 27 | | 1 (0)| 00:00:01 |
|* 18 | SORT JOIN | | 107 | 2033 | 4 (25)| 00:00:01 |
| 19 | TABLE ACCESS FULL | EMPLOYEES | 107 | 2033 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("JOBS"."JOB_TITLE"='President')
2 - access("JOBS"."JOB_ID"=:B1)
3 - filter("JOBS"."JOB_TITLE"='Administration Vice President')
4 - access("JOBS"."JOB_ID"=:B1)
5 - filter("JOBS"."JOB_TITLE"='Administration Assistant')
6 - access("JOBS"."JOB_ID"=:B1)
7 - filter("JOBS"."JOB_TITLE"='Finance Manager')
8 - access("JOBS"."JOB_ID"=:B1)
9 - filter("JOBS"."JOB_TITLE"='Public Accountant')
10 - access("JOBS"."JOB_ID"=:B1)
11 - filter("JOBS"."JOB_TITLE"='Purchasing Manager')
12 - access("JOBS"."JOB_ID"=:B1)
14 - access("LOCATIONS"."LOCATION_ID"=:B1)
18 - access("EMPLOYEES"."DEPARTMENT_ID"="DEPARTMENTS"."DEPARTMENT_ID")
filter("EMPLOYEES"."DEPARTMENT_ID"="DEPARTMENTS"."DEPARTMENT_ID")
已选择45行。
修改SQL:
select e.first_name,
d.department_name,
nvl(j.pre_min_sal, 0) pre_min_sal,
nvl(j.avp_sal, 0) avp_sal,
nvl(j.aa_sal, 0) aa_sal,
nvl(j.fm_sal, 0) fm_sal,
nvl(j.pa_sal, 0) pa_sal,
nvl(j.pm_sal, 0) pm_sal,
nvl(l.city, 0) city
from employees e
left outer join (select j1.job_id,
decode(job_title, 'President', min_salary) pre_min_sal,
decode(job_title,
'Administration Vice President',
min_salary) avp_sal,
decode(job_title,
'Administration Assistant',
min_salary) aa_sal,
decode(job_title, 'Finance Manager', max_salary) fm_sal,
decode(job_title, 'Public Accountant', max_salary) pa_sal,
decode(job_title, 'Purchasing Manager', max_salary) pm_sal
from jobs j1
where job_title in ('President',
'Administration Vice President',
'Administration Assistant',
'Finance Manager',
'Public Accountant',
'Purchasing Manager')) j
on (j.job_id = e.job_id)
inner join departments d
on (e.department_id = d.department_id)
left outer join locations l
on (d.location_id = l.location_id);
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------
Plan hash value: 1485523108
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 106 | 8798 | 13 (24)| 00:00:01 |
|* 1 | HASH JOIN RIGHT OUTER | | 106 | 8798 | 13 (24)| 00:00:01 |
| 2 | VIEW | index$_join$_007 | 23 | 276 | 3 (34)| 00:00:01 |
|* 3 | HASH JOIN | | | | | |
| 4 | INDEX FAST FULL SCAN | LOC_CITY_IX | 23 | 276 | 1 (0)| 00:00:01 |
| 5 | INDEX FAST FULL SCAN | LOC_ID_PK | 23 | 276 | 1 (0)| 00:00:01 |
|* 6 | HASH JOIN OUTER | | 106 | 7526 | 10 (20)| 00:00:01 |
| 7 | MERGE JOIN | | 106 | 4028 | 6 (17)| 00:00:01 |
| 8 | TABLE ACCESS BY INDEX ROWID| DEPARTMENTS | 27 | 513 | 2 (0)| 00:00:01 |
| 9 | INDEX FULL SCAN | DEPT_ID_PK | 27 | | 1 (0)| 00:00:01 |
|* 10 | SORT JOIN | | 107 | 2033 | 4 (25)| 00:00:01 |
| 11 | TABLE ACCESS FULL | EMPLOYEES | 107 | 2033 | 3 (0)| 00:00:01 |
|* 12 | TABLE ACCESS FULL | JOBS | 6 | 198 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("D"."LOCATION_ID"="L"."LOCATION_ID"(+))
3 - access(ROWID=ROWID)
6 - access("J1"."JOB_ID"(+)="E"."JOB_ID")
10 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
filter("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")
12 - filter("JOB_TITLE"(+)='Administration Assistant' OR "JOB_TITLE"(+)='Administration
Vice President' OR "JOB_TITLE"(+)='Finance Manager' OR "JOB_TITLE"(+)='President' OR
"JOB_TITLE"(+)='Public Accountant' OR "JOB_TITLE"(+)='Purchasing Manager')