I take this simple Correlated Subquery that identifies all employees whose Salary is greater than the department's average Salary and is also greater than $9,000
The Row Source Statistics for the actual query execution are :
The Execution Plan is
(Since I had only 1 execution of the query when tracing is enabled, "Rows (1st"), "Rows (avg)" and "Rows (max)" report on the same, single, execution)
The EMPLOYEES table underwent two Full Table Scans, each consisting of 6 "consistent reads" ("cr=6").
The execution at line Id=4 expected to return 73 rows ("card=73") but actually returned 23 rows. This query filtered for SALARY greater than 9000.
The execution at line Id=5 expected to return 108 rows ("card=108") and did actually return 108 rows. There is no predicate information, meaning that all 108 rows of the table were returned, none filtered.
The join of the outer query and the inner query on DEPARTMENT_ID was the Hash Join at operation Id=3.
Do you note how the FILTER at operation ID=1 appears ? It is filtering for SALARY greater than AVERAGE SALARY (where AVERAGE is computed as SUM of SALARY values divided by the number of not-null SALARY values)
SQL> l 1 select emp.department_id, emp.employee_id, emp.salary 2 from hr.employees emp 3 where emp.salary > 4 (select avg(salary) 5 from hr.employees emp_inner 6 where emp.department_id = emp_inner.department_id) 7 and emp.salary > 9000 8* order by 1,2 SQL> / DEPARTMENT_ID EMPLOYEE_ID SALARY ------------- ----------- ---------- 20 201 13000 30 114 11000 80 145 14000 80 146 13500 80 147 12000 80 148 11000 80 149 10500 80 150 10000 80 151 9500 80 156 10000 80 157 9500 80 162 10500 80 163 9500 80 168 11500 80 169 10000 80 170 9600 80 174 11000 90 100 24000 100 108 12008 110 205 12008 20 rows selected. SQL>
The Row Source Statistics for the actual query execution are :
select emp.department_id, emp.employee_id, emp.salary from hr.employees emp where emp.salary > (select avg(salary) from hr.employees emp_inner where emp.department_id = emp_inner.department_id) and emp.salary > 9000 order by 1,2 call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 3 0.00 0.00 0 12 0 20 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 5 0.00 0.00 0 12 0 20 Misses in library cache during parse: 1 Optimizer mode: ALL_ROWS Parsing user id: 106 Number of plan statistics captured: 1 Rows (1st) Rows (avg) Rows (max) Row Source Operation ---------- ---------- ---------- --------------------------------------------------- 20 20 20 FILTER (cr=12 pr=0 pw=0 time=1027 us starts=1) 23 23 23 SORT GROUP BY (cr=12 pr=0 pw=0 time=1020 us starts=1 cost=7 size=3552 card=111) 536 536 536 HASH JOIN (cr=12 pr=0 pw=0 time=917 us starts=1 cost=6 size=71648 card=2239) 23 23 23 TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=30 us starts=1 cost=3 size=1752 card=73) 108 108 108 TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=7 us starts=1 cost=3 size=864 card=108) ********************************************************************************
The Execution Plan is
---------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 111 | 3552 | 7 (15)| 00:00:01 | |* 1 | FILTER | | | | | | | 2 | SORT GROUP BY | | 111 | 3552 | 7 (15)| 00:00:01 | |* 3 | HASH JOIN | | 2239 | 71648 | 6 (0)| 00:00:01 | |* 4 | TABLE ACCESS FULL| EMPLOYEES | 73 | 1752 | 3 (0)| 00:00:01 | | 5 | TABLE ACCESS FULL| EMPLOYEES | 108 | 864 | 3 (0)| 00:00:01 | ---------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("EMP"."SALARY">SUM("SALARY")/COUNT("SALARY")) 3 - access("EMP"."DEPARTMENT_ID"="EMP_INNER"."DEPARTMENT_ID") 4 - filter("EMP"."SALARY">9000)
(Since I had only 1 execution of the query when tracing is enabled, "Rows (1st"), "Rows (avg)" and "Rows (max)" report on the same, single, execution)
The EMPLOYEES table underwent two Full Table Scans, each consisting of 6 "consistent reads" ("cr=6").
The execution at line Id=4 expected to return 73 rows ("card=73") but actually returned 23 rows. This query filtered for SALARY greater than 9000.
The execution at line Id=5 expected to return 108 rows ("card=108") and did actually return 108 rows. There is no predicate information, meaning that all 108 rows of the table were returned, none filtered.
The join of the outer query and the inner query on DEPARTMENT_ID was the Hash Join at operation Id=3.
Do you note how the FILTER at operation ID=1 appears ? It is filtering for SALARY greater than AVERAGE SALARY (where AVERAGE is computed as SUM of SALARY values divided by the number of not-null SALARY values)
No comments:
Post a Comment