oracle12c join techniques
DESCRIPTION
Introduction Working with Oracle since 1986 Oracle DBA - OCP Oracle7, 8, 9, 10 Oracle DBA of the Year – 2002 Oracle ACE Director Beta tester – Oracle8, 9, 10, 11, 12 Regular Presenter at Oracle Conferences Consultant and Trainer Technical Editor for a number of Oracle texts UK Oracle User Group Official Member of IOUC Fellow of British Computer Society ANSI and Oracle Joins Two-way Outer Joins Join and Filter Conditions Chaining on the Outer Join Hash Join Trees Anti Joins and Semi Joins Lateral Joins Nested Loops Joins Join Elimination Adaptive JoinsTRANSCRIPT
Introduction
ANSI and Oracle Joins
Two-way Outer Joins
Join and Filter Conditions
Chaining on the Outer Join
Hash Join Trees
Anti Joins and Semi Joins
Lateral Joins
Nested Loops Joins
Join Elimination
Adaptive Joins
2
Working with Oracle since 1986Oracle DBA - OCP Oracle7, 8, 9, 10Oracle DBA of the Year – 2002Oracle ACE DirectorBeta tester – Oracle8, 9, 10, 11, 12Regular Presenter at Oracle ConferencesConsultant and TrainerTechnical Editor for a number of Oracle textsUK Oracle User Group OfficialMember of IOUCFellow of British Computer Society
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO----- ---------- --------- ----- ----------- ----- ----- ------ 7934 MILLER CLERK 7782 23-JAN-1982 1300 10 7782 CLARK MANAGER 7839 09-JUN-1981 2450 10 7839 KING PRESIDENT 17-NOV-1981 5000 10 7369 SMITH CLERK 7902 17-DEC-1980 800 20 7876 ADAMS CLERK 7788 12-JAN-1983 1100 20 7566 JONES MANAGER 7839 02-APR-1981 2975 20 7902 FORD ANALYST 7566 03-DEC-1981 3000 20 7788 SCOTT ANALYST 7566 09-DEC-1982 3000 20 7900 JAMES CLERK 7698 03-DEC-1981 950 30 7521 WARD SALESMAN 7698 22-FEB-1981 1250 500 30 7654 MARTIN SALESMAN 7698 28-SEP-1981 1250 1400 30 7844 TURNER SALESMAN 7698 08-SEP-1981 1500 0 30 7499 ALLEN SALESMAN 7698 20-FEB-1981 1600 300 30 7698 BLAKE MANAGER 7839 01-MAY-1981 2850 30
DEPTNO DNAME LOC------ -------------- -------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON
dept
emp
The emp and dept Tables
3
ANSI Joins
ANSI defined join syntax in ANSI SQL2 Standard (1992)— Oracle finally fully implemented this syntax in Oracle9i
Types of joins specified by additional keywords
INNER JOIN
OUTER JOIN (LEFT RIGHT FULL)
CROSS JOIN
UNION JOIN (not supported by Oracle)
4
Inner Joins – ANSI and Oracle Syntax
Equivalent ANSI – based joinsSELECT ename,dname,dept.deptnoFROM emp JOIN dept ON dept.deptno = emp.deptno;
SELECT ename,dname,deptnoFROM emp NATURAL JOIN deptUSING (deptno);
— Note the absence of the table qualifier for deptno in some of the examples
Equivalent Oracle join
SELECT ename,dname,dept.deptnoFROM emp,dept WHERE emp.deptno = dept.deptno;
SELECT ename,dname,deptnoFROM emp NATURAL JOIN dept;
5
The Join Condition
SELECT ename,dname,dept.deptnoFROM emp JOIN dept;
ORA-00905: missing keyword
But join condition does not have to make any sense— Could cause cartesian products
— Oracle join syntax has no protection
Join condition (ON clause) must be included ― Helps safeguard against inadvertant cartesian products
SELECT ename,dname,dept.deptnoFROM emp JOIN deptON emp.empno = emp.empno;
6
Multi-table Joins
If several tables are to be joined— Use a step-wise process by first joining two of the tables— Then add a further JOIN keyword to join to the third table— Repeat this for each subsequent table— Each join may have its own condition(s)— The joins may be of different types
SELECT emp.empno ,emp.ename ,dept.loc ,proj.pnameFROM empJOIN deptON emp.deptno = dept.deptnoJOIN projON emp.proj_id = proj.proj_id;
7
LEFT and RIGHT Outer Joins
The driving table is specified with LEFT or RIGHT— This table will have all its rows included— Dummy NULL rows may be included from the other table
Refers to placement of the table name WITHIN the FROM ... JOIN clause
The following join clauses are all equivalent
FROM emp,dept WHERE emp.deptno(+) = dept.deptno
FROM dept LEFT OUTER JOIN empON emp.deptno = dept.deptno
FROM emp RIGHT OUTER JOIN deptON emp.deptno = dept.deptno
8
Modified Employee Data
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO----- ------ -------- ----- ----------- ---- ----- ------- 7782 CLARK MANAGER 7839 09-JUN-1981 2450 10 7788 SCOTT ANALYST 7566 19-APR-1987 3000 20 7844 TURNER SALESMAN 7698 08-SEP-1981 1500 0 30 7499 ALLEN SAlESMAN 7698 20-FEB-1981 1600 300 30 7902 FORD ANALYST 7566 03-DEC-1981 3000 20 1111 EXTRA CEO 01-JAN-1999 500
DEPTNO DNAME LOC------- ---------- -------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON
empa
dept
9
RIGHT Outer Joins
ENAME DNAME DEPTNO------- ------------ ------CLARK ACCOUNTING 10SCOTT RESEARCH 20TURNER SALES 30FORD RESEARCH 20ALLEN SALES 30 OPERATIONS 40
SELECT ename,dname,dept.deptnoFROM empa RIGHT OUTER JOIN dept ON empa.deptno = dept.deptno;
SELECT ename,dname,dept.deptnoFROM empa,dept WHERE dept.deptno = emp.deptno(+);
Equivalent Oracle join statement
10
LEFT Outer Joins
ENAME DNAME DEPTNO------- ------------ ------CLARK ACCOUNTING 10SCOTT RESEARCH 20TURNER SALES 30FORD RESEARCH 20ALLEN SALES 30EXTRA
SELECT ename,dname,dept.deptnoFROM empa LEFT OUTER JOIN deptON empa.deptno = dept.deptno;
SELECT ename,dname,dept.deptnoFROM empa, dept WHERE dept.deptno(+) = empa.deptno;
Equivalent Oracle join statement
11
FULL Outer Joins
ENAME DNAME D_DEPTNO E_DEPTNO------- ------------ -------- --------CLARK ACCOUNTING 10 10SCOTT RESEARCH 20 20TURNER SALES 30 30FORD RESEARCH 20 20ALLEN SALES 30 30EXTRA OPERATIONS 40
SELECT ename,dname,dept.deptno d_deptno, empa.deptno e_deptnoFROM empa FULL OUTER JOIN dept ON empa.deptno = dept.deptno;
SELECT ename,dname,dept.deptno,empa.deptnoFROM empa, dept WHERE dept.deptno(+) = empa.deptno(+);
Equivalent (ILLEGAL) Oracle join statement
All rows included from both tables
12
FULL OUTER JOIN – Oracle11g
Oracle now performs a 'NATIVE' full outer joinSELECT ename ,dnameFROM empa e FULL OUTER JOIN dept d ON e.deptno = d.deptno;
---------------------------------------------------------------| Id | Operation | Name |Rows |Bytes |Cost(%CPU---------------------------------------------------------------| 0| SELECT STATEMENT | | 15 | 240 | 7 (15| 1| VIEW | VW_FOJ_0 | 15 | 240 | 7 (15|* 2| HASH JOIN FULL OUTER| | 15 | 330 | 7 (15| 3| TABLE ACCESS FULL | DEPT | 4 | 52 | 3 (0| 4| TABLE ACCESS FULL | EMPA | 14 | 126 | 3 (0---------------------------------------------------------------
13
FULL OUTER JOIN – Oracle10g
SELECT ename ,dnameFROM empa e FULL OUTER JOIN dept dON e.deptno = d.deptno;
------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost |------------------------------------------------------------| 0 | SELECT STATEMENT | | 15 | 240 | 13|| 1 | VIEW | | 15 | 240 | 13|| 2 | UNION-ALL | | | | ||* 3 | HASH JOIN OUTER | | 14 | 308 | 7|| 4 | TABLE ACCESS FULL| EMPA | 14 | 126 | 3|| 5 | TABLE ACCESS FULL| DEPT | 4 | 52 | 3||* 6 | HASH JOIN ANTI | | 1 | 16 | 7|| 7 | TABLE ACCESS FULL| DEPT | 4 | 52 | 3|| 8 | TABLE ACCESS FULL| EMPA | 14 | 42 | 3|------------------------------------------------------------
ALTER SESSION SET optimizer_features_enable = '10.2.0.1';
14
FULL OUTER JOIN – Oracle10g (continued)
Statement is transformed to a UNION construct
― Generates same execution plan as for 10g FULL OUTER JOIN
Native full outer join available in 10.2.0.3 and 10.2.0.4 with a hint/*+NATIVE_FULL_OUTER_JOIN */
Undocumented parameter_optimizer_native_full_outer_join
SELECT ename ,dnameFROM empa e ,dept dWHERE e.deptno = d.deptno(+)UNION ALLSELECT null ,dnameFROM dept d2 WHERE NOT EXISTS (SELECT 'x' FROM empa e2 WHERE e2.deptno = d2.deptno);
15
Oracle12c Join Techniques
ANSI and Oracle Joins
Two-way Outer Joins
Join and Filter Conditions
Chaining on the Outer Join
Hash Join Trees
Anti Joins and Semi Joins
Lateral Joins
Nested Loops Joins
Join Elimination
Adaptive Joins
16
Two-way Outer Joins
project table linked to a cut down modified version of emp, called empb― Project number 3 (DESIGN) has no employees
PROJ_ID PNAME START_DATE------- --------- ----------- 1 BPR 01-JUL-2002 2 MIGRATION 12-OCT-2002 3 DESIGN 01-NOV-2002
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO PROJ_ID----- ------ -------- ---- ----------- ---- ---- ------ ------- 7782 CLARK MANAGER 7839 09-JUN-1981 2450 10 1 7788 SCOTT ANALYST 7566 19-APR-1987 3000 20 2 7844 TURNER SALESMAN 7698 08-SEP-1981 1500 0 30 1 7499 ALLEN SAlESMAN 7698 20-FEB-1981 1600 300 30 1
17
DEPTNO DNAME LOC------- ---------- -------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON
deptproj
empb
Two-way Outer Joins
Show details of employees with their projects and departments— Include projects with no employees and departments with no employees
project empb dept(+) (+)
18
ANSI Two-way Outer Joins – Expected result
ENAME HIREDATE DEPTNO DNAME PROJ_ID PNAME---------- ----------- ------ ----------- ------- ---------ALLEN 20-FEB-1981 30 SALES 1 BPRTURNER 08-SEP-1981 30 SALES 1 BPRCLARK 09-JUN-1981 10 ACCOUNTING 1 BPRSCOTT 19-APR-1987 20 RESEARCH 2 MIGRATION 40 OPERATIONS 3 DESIGN
Two-way outer joins are allowed but the result may not be as expected
Outer join of empb to both dept and project based on deptno and proj_id values (as requested on the previous slide) should give the following result
19
ANSI Two-way Outer Joins – Missing Rows
Unexpected results?
SELECT ename, hiredate,d.deptno,dname,p.proj_id,pnameFROM dept d LEFT OUTER JOIN empb e ON e.deptno = d.deptnoRIGHT OUTER JOIN proj pON e.proj_id = p.proj_id;
ENAME HIREDATE DEPTNO DNAME PROJ_ID PNAME---------- ----------- ------ ----------- ------- ---------CLARK 09-JUN-1981 10 ACCOUNTING 1 BPR SCOTT 19-APR-1987 20 RESEARCH 2 MIGRATIONALLEN 20-FEB-1981 30 SALES 1 BPRTURNER 08-SEP-1981 30 SALES 1 BPR 3 DESIGN
20
ANSI Two-way Outer Joins – Missing Rows (continued)
Reordering the joins still gives another different unexpected result?― Outer joins are not 'symmetrical'
SELECT ename, hiredate,d.deptno,dname,p.proj_id,pnameFROM proj p LEFT OUTER JOIN empb e ON e.proj_id = p.proj_idRIGHT OUTER JOIN dept dON e.deptno = d.deptno;
ENAME HIREDATE DEPTNO DNAME PROJ_ID PNAME---------- ----------- ------ ----------- ------- ---------CLARK 09-JUN-1981 10 ACCOUNTING 1 BPR SCOTT 19-APR-1987 20 RESEARCH 2 MIGRATIONTURNER 08-SEP-1981 30 SALES 1 BPR ALLEN 20-FEB-1981 30 SALES 1 BPR 40 OPERATIONS
21
ANSI Two-way Outer Joins - Explanation
Explanation of unexpected behaviour— Examine the result of the first join in the first example— The fifth row does not have a value in the proj_id column— This row can not take part in the final join with the proj table
SELECT ename, hiredate,d.deptno,dname,proj_idFROM dept d LEFT OUTER JOIN empb e ON e.deptno = d.deptno;
ENAME HIREDATE DEPTNO DNAME PROJ_ID---------- ----------- ------ ----------- -------CLARK 09-JUN-1981 10 ACCOUNTING 1 SCOTT 19-APR-1987 20 RESEARCH 2TURNER 08-SEP-1981 30 SALES 1 ALLEN 20-FEB-1981 30 SALES 1 40 OPERATIONS
22
ANSI Two-way Outer Joins – use of FULL
ENAME HIREDATE DEPTNO DNAME PROJ_ID PNAME---------- ----------- ------ ----------- ------- ---------ALLEN 20-FEB-1981 30 SALES 1 BPRTURNER 08-SEP-1981 30 SALES 1 BPRCLARK 09-JUN-1981 10 ACCOUNTING 1 BPRSCOTT 19-APR-1987 20 RESEARCH 2 MIGRATION 40 OPERATIONS 3 DESIGN
SELECT ename,hiredate,d.deptno,dname,p.proj_id,pnameFROM dept d LEFT OUTER JOIN empb e ON e.deptno = d.deptnoFULL OUTER JOIN proj pON e.proj_id = p.proj_id;
Outer joining dept to empb gives a row with NULL in proj_id― This row can not take part in the second outer join― The second join needs to be a FULL OUTER JOIN
23
SELECT STATEMENT | VIEW | VW_FOJ_0 HASH JOIN FULL OUTER| TABLE ACCESS FULL | PROJ VIEW | HASH JOIN OUTER | TABLE ACCESS FULL| DEPT TABLE ACCESS FULL| EMPB
Two-way Outer Joins – Oracle Style
In 11g, Oracle syntax cannot outer join a table to more than one other table
ORA-01417: a table may be outer joined to at most one other table
SELECT ename,hiredate,d.deptno,dname,p.proj_id,pnameFROM dept d, empb e, proj pWHERE e.deptno(+) = d.deptnoAND e.proj_id(+) = p.proj_id;
24
Two-way Outer Joins – Oracle Style (continued)
But in Oracle12c, this would be the output
ENAME HIREDATE DEPTNO DNAME PROJ_ID PNAME------------- ----------- ------ ----------- ------- ----------SCOTT 19-APR-1987 20 RESEARCH 2 MIGRATION ALLEN 20-FEB-1981 30 SALES 1 BPRTURNER 08-SEP-1981 30 SALES 1 BPRCLARK 09-JUN-1981 10 ACCOUNTING 1 BPR 40 OPERATIONS 1 BPR 40 OPERATIONS 2 MIGRATION 40 OPERATIONS 3 DESIGN 30 SALES 2 MIGRATION 30 SALES 3 DESIGN 20 RESEARCH 1 BPR 20 RESEARCH 3 DESIGN 10 ACCOUNTING 2 MIGRATION 10 ACCOUNTING 3 DESIGN
25
SELECT ename,hiredate,d.deptno,dname,p.proj_id,pnameFROM dept d CROSS JOIN proj pLEFT OUTER JOIN empb eON e.deptno = d.deptno AND e.proj_id = p.proj_id
Can be imitated using ANSI syntax
SELECT STATEMENT | HASH JOIN OUTER | MERGE JOIN CARTESIAN| TABLE ACCESS FULL | PROJ BUFFER SORT | TABLE ACCESS FULL | DEPT TABLE ACCESS FULL | EMPB
Oracle Outer Joins with Subqueries
ORA-01799: a column may not be outer-joined to a subquery
SELECT ename, hiredate,d.deptno,dnameFROM dept d, empa eWHERE e.deptno(+) = d.deptnoAND e.hiredate(+) = (SELECT MIN(e.hiredate) FROM empa e WHERE e.deptno = d.deptno);
Show each department with its longest serving employee— Subqueries are not allowed in combination with an outer join condition
What about ANSI joins?
26
SELECT ename, hiredate,d.deptno,dnameFROM dept d LEFT OUTER JOIN emp eON e.deptno = d.deptnoAND e.hiredate = (SELECT MIN(e.hiredate) FROM emp e WHERE e.deptno = d.deptno);
ENAME HIREDATE DEPTNO DNAME---------- --------- ---------- ----------CLARK 09-JUN-81 10 ACCOUNTINGSMITH 17-DEC-80 20 RESEARCHALLEN 20-FEB-81 30 SALES 40 OPERATIONS
Oracle12c Join Techniques
ANSI and Oracle Joins
Two-way Outer Joins
Join and Filter Conditions
Chaining on the Outer Join
Hash Join Trees
Anti Joins and Semi Joins
Lateral Joins
Nested Loops Joins
Join Elimination
Adaptive Joins
27
Join and Filter Conditions
Oracle uses the ON clause for join conditions
Conditions specified in a WHERE clause are treated as filter conditions
Filter conditions can also be specified in the ON (or USING) clause
Join operations and conditions are effectively processed before the WHERE clause conditions
28
Oracle Join and Filter Conditions
SELECT dept.deptno,dname,ename,jobFROM dept, empaWHERE empa.deptno(+) = dept.deptnoAND empa.job(+) = 'SALESMAN';DEPTNO DNAME ENAME JOB------ ----------- -------- -------- 10 ACCOUNTING 20 RESEARCH 30 SALES TURNER SALESMAN 30 SALES ALLEN SALESMAN 40 OPERATIONS
SELECT dept.deptno,dname,ename,jobFROM dept, empaWHERE empa.deptno(+) = dept.deptnoAND empa.job = 'SALESMAN';DEPTNO DNAME ENAME JOB------ ----------- -------- -------- 30 SALES TURNER SALESMAN 30 SALES ALLEN SALESMAN
Filter applied after the join
Filter applied during the join— Somewhat awkward syntax
29
ANSI Join and Filter Conditions
SELECT dept.deptno,dname,ename,jobFROM dept LEFT OUTER JOIN empaON empa.deptno = dept.deptnoAND empa.job = 'SALESMAN';
DEPTNO DNAME ENAME JOB------ ----------- ------- -------- 30 SALES TURNER SALESMAN 30 SALES ALLEN SALESMAN 40 OPERATIONS 20 RESEARCH 10 ACCOUNTING
SELECT dept.deptno,dname,ename,jobFROM dept LEFT OUTER JOIN empaON empa.deptno = dept.deptnoWHERE empa.job = 'SALESMAN‘;DEPTNO DNAME ENAME JOB------ ---------- -------- -------- 30 SALES ALLEN SALESMAN 30 SALES TURNER SALESMAN
Filter applied after the join— Easier to understand due to separation of join conditions from filter conditions
Filter applied during the join
Note the three outer joined rows- one row for each department having no salesmen
30
Oracle Outer Joins and OR
Oracle syntax cannot cope
SELECT dname ,ename ,job ,loc ,salFROM emp e ,dept dWHERE e.deptno(+) = d.deptnoAND (sal(+) > 2999 OR loc(+) = ‘NEW YORK')ORDER BY dname;
31
AND (sal(+) > 2999 OR loc(+) = ‘NEW YORK') ERROR :ORA-01719:outer join operator (+) not allowed in operand of OR or IN
ANSI Outer Joins and OR
ANSI join can process OR when combined with outer joinSELECT dname ,ename ,job ,loc ,salFROM emp e RIGHT OUTER JOIN dept dON e.deptno = d.deptnoAND (sal > 2999 OR loc = 'NEW YORK')ORDER BY dname;
DNAME ENAME JOB LOC SAL-------------- ---------- --------- ------------- ----ACCOUNTING CLARK MANAGER NEW YORK 2450ACCOUNTING KING PRESIDENT NEW YORK 5000ACCOUNTING MILLER CLERK NEW YORK 1300OPERATIONS BOSTONRESEARCH FORD ANALYST DALLAS 3000RESEARCH SCOTT ANALYST DALLAS 3000SALES CHICAGO
32
Oracle12c Join Techniques
ANSI and Oracle Joins
Two-way Outer Joins
Join and Filter Conditions
Chaining on the Outer Join
Hash Join Trees
Anti Joins and Semi Joins
Lateral Joins
Nested Loops Joins
Join Elimination
Adaptive Joins
33
'Chaining on' the Outer Join
course attendance student
All courses have attendances, all attendances have offerings― Hence outer join is never necessary when joining offering and attendance
Some students do not have attendances
Query :
Show ALL students along with their courses
34
Data in the Sample Tables
COURSE_ID START_DATE--------- ---------- 1001 14-DEC-11 1002 12-JUL-12 1003 20-NOV-12
COURSE_ID STUDENT_ID --------- ---------- 1001 1111 1002 2299 1003 2299 1002 6789 1003 1111
STUDENT_ID STUDENT_LNAME---------- ------------- 1111 BROWN 2299 ADAMS 4568 COX 5556 TYLER 6789 ROSE
Two students do not have any attendances
All courses and attendances are related― Outer join between these tables should NOT be needed
35
course
attendance
student
Joining course and attendance
Outer join is completely unnecessary as all rows match
C_COURSE_ID A_COURSE_ID A_STUDENT_ID----------- ----------- ------------ 1001 1001 1111 1002 1002 2299 1003 1003 2299 1002 1002 6789 1003 1003 1111
SELECT c.course_id c_course_id ,a.course_id a_course_id ,a.student_id FROM course c INNER JOIN attendance aON c.course_id = a.course_id;
SELECT o.course_id c_course_id ,a.course_id a_course_id ,a.student_id a_student_id FROM attendance a LEFT OUTER JOIN course cON a.course_id = c.course_id;
36
Exact same result
Joining attendance and student
Outer join is necessary to include students without attendances
SELECT s.student_id s_student_id ,s.student_lname s_student_lname ,a.student_id a_student_id ,a.course_id a_course_id FROM student s LEFT OUTER JOIN attendance aON s.student_id = a.student_id;
S_STUDENT_ID S_LNAME A_STUDENT_ID A_COURSE_ID------------ ------- ------------ ----------- 1111 BROWN 1111 1001 2299 ADAMS 2299 1002 2299 ADAMS 2299 1003 6789 ROSE 6789 1002 1111 BROWN 1111 1003 4568 COX 5556 TYLER
37
Join the Three Tables - inner join 'loses' students
Rows are lost by the final inner join Oracle is smart enough
not to perform the outer join
SELECT s.student_id s_student_id,s.student_lname s_lname ,a.student_id a_student_id,a.course_id a_course_id ,c.course_id c_course_id,c.start_date FROM student s LEFT OUTER JOIN attendance aON s.student_id = a.student_id INNER JOIN course cON c.course_id = a.course_id;
S_STUDENT_ID S_LNAME A_STUDENT_ID A_COURSE_ID C_COURSE_ID START_DATE------------ ------- ------------ ----------- ----------- ---------- 1111 BROWN 1111 1001 1001 14-DEC-11 2299 ADAMS 2299 1002 1002 12-JUL-12 2299 ADAMS 2299 1003 1003 20-NOV-12 6789 ROSE 6789 1002 1002 12-JUL-12 1111 BROWN 1111 1003 1003 20-NOV-12
-----------------------------------------------| Id | Operation | Name |Rows |-----------------------------------------------| 0| SELECT STATEMENT | | 5||* 1| HASH JOIN | | 5||* 2| HASH JOIN | | 5|| 3| TABLE ACCESS FULL| COURSE | 3|| 4| TABLE ACCESS FULL| ATTENDANCE | 5|| 5| TABLE ACCESS FULL | STUDENT | 5|-----------------------------------------------
38
Chaining on the OUTER JOINSELECT s.student_id s_student_id,s.student_lname s_lname ,a.student_id a_student_id,a.course_id a_course_id ,c.course_id c_course_id,c.start_date FROM student s LEFT OUTER JOIN attendance aON s.student_id = a.student_id LEFT OUTER JOIN course cON c.course_id = a.course_id;
S_STUDENT_ID S_LNAME A_STUDENT_ID A_COURSE_ID C_COURSE_ID START_DATE------------ ------- ------------ ----------- ----------- ---------- 1111 BROWN 1111 1001 1001 14-DEC-11 2299 ADAMS 2299 1002 1002 12-JUL-12 2299 ADAMS 2299 1003 1003 20-NOV-12 6789 ROSE 6789 1002 1002 12-JUL-12 1111 BROWN 1111 1003 1003 20-NOV-12 4568 COX 5556 TYLER
-----------------------------------------------| Id | Operation | Name |Rows |-----------------------------------------------| 0| SELECT STATEMENT | | 5||* 1| HASH JOIN OUTER | | 5||* 2| HASH JOIN OUTER | | 5|| 3| TABLE ACCESS FULL| STUDENT | 5|| 4| TABLE ACCESS FULL| ATTENDANCE | 5|| 5| TABLE ACCESS FULL | COURSE | 3|-----------------------------------------------
Outer join must be performed between attendance and course when not strictly necessary
39
Avoiding the second OUTER JOIN
Inner join performed first
Outer join preserves all student rows
SELECT s.student_id s_student_id,s.student_lname s_lname ,a.student_id a_student_id,a.course_id a_course_id ,c.course_id c_course_id,c.start_dateFROM course c JOIN attendance aON c.course_id = a.course_id RIGHT OUTER JOIN student sON s.student_id = a.student_id;
S_STUDENT_ID S_LNAME A_STUDENT_ID A_COURSE_ID C_COURSE_ID START_DATE------------ ------- ------------ ----------- ----------- ---------- 1111 BROWN 1111 1001 1001 14-DEC-11 2299 ADAMS 2299 1002 1002 12-JUL-12 2299 ADAMS 2299 1003 1003 20-NOV-12 6789 ROSE 6789 1002 1002 12-JUL-12 1111 BROWN 1111 1003 1003 20-NOV-12 4568 COX 5556 TYLER
------------------------------------------------| Id | Operation | Name |Rows |------------------------------------------------| 0| SELECT STATEMENT | | 5||* 1| HASH JOIN OUTER | | 5|| 2| TABLE ACCESS FULL | STUDENT | 5|| 3| VIEW | | 5||* 4| HASH JOIN | | 5|| 5| TABLE ACCESS FULL| COURSE | 3|| 6| TABLE ACCESS FULL| ATTENDANCE | 5|------------------------------------------------
40
Ordering the joins 'Right'SELECT s.student_id s_student_id,s.student_lname s_lname ,a.student_id a_student_id,a.course_id a_course_id ,c.course_id c_course_id,c.start_date FROM attendance a RIGHT OUTER JOIN student sON s.student_id = a.student_id JOIN course cON c.course_id = a.course_id;
S_STUDENT_ID S_LNAME A_STUDENT_ID A_COURSE_ID C_COURSE_ID START_DATE------------ ------- ------------ ----------- ----------- ---------- 1111 BROWN 1111 1001 1001 14-DEC-11 2299 ADAMS 2299 1002 1002 12-JUL-12 2299 ADAMS 2299 1003 1003 20-NOV-12 6789 ROSE 6789 1002 1002 12-JUL-12 1111 BROWN 1111 1003 1003 20-NOV-12
-----------------------------------------------| Id | Operation | Name |Rows |-----------------------------------------------| 0| SELECT STATEMENT | | 5||* 1 HASH JOIN | | 5||* 2| HASH JOIN | | 5|| 3| TABLE ACCESS FULL| COURSE | 3|| 4| TABLE ACCESS FULL| ATTENDANCE | 5|| 5| TABLE ACCESS FULL | STUDENT | 5|-----------------------------------------------
Right join would be performed first?
Inner join would then lose the outer joined student rows
No outer joins performed
41
Oracle12c Join Techniques
ANSI and Oracle Joins
Two-way Outer Joins
Join and Filter Conditions
Chaining on the Outer Join
Hash Join Trees
Anti Joins and Semi Joins
Lateral Joins
Nested Loops Joins
Join Elimination
Adaptive Joins
42
Processing a Hash Join
NAME CITY ...SCOTT BATH ...
PAYNE YORK ...
FOX LEEDS ...
SMITH ELY ...
WOOD BATH ...
ADAMS LONDON ...
ADAMS LONDON ...FOX LEEDS ...
PAYNE YORK ...
SCOTT BATH ...
WOOD BATH ...SMITH ELY ...
ORD_ID NAME ...1 SMITH ...
2 PAYNE ...
3 FOX ...
4 SCOTT ...
5 WOOD ...
6 ADAMS ...
Hash table
Build Table (customers)
Probe Table (orders)43
Join Trees for T1 T2 T3 T4
T2T1
T3
T4
Left deep tree
Output of T1 join T2 probed by T3
Output of T1 join T2 join T3 probed by T4
Hash table built on T1 probed by T2
T2 T1
T3
T4
Right deep tree
Hash table built on T3probed by result of T1 join T2
Hash table built on T2probed by T1
Hash table built on T4probed by result of T1 join T2 join T3
44
Summary of Left-deep and Right-deep Hash Join Trees
Left-deep― Result sets are formed before build of next hash table― Workarea discarded after each subsequent join― Only one workarea used
Right-deep― Hash tables on T3 and T4 can be built 'in parallel' with hash table on T1
― Three workareas can be used― Could be useful when the results of joins are larger than the two sets of
rows being joined
45
Bushy tree
T2T1 T3 T4 T2T1
T3
T4
Zig-zag tree
46
Join Trees for T1 T2 T3 T4 (continued)
Tree Combinations
Tables Left-Deep Trees Bushy Trees(inc. Left and Right)
1 1 1 2 2 2 3 6 12 4 24 120 5 120 1,680 6 720 30,240
Optimizer normally considers only left-deep trees (until latest release?)― Left deep joins cover most requirements― Number of left-deep trees = n!― Total number of join trees = (2n-2)!/(n-1)!
Can Oracle be forced to perform a bushy tree?
47
Four Table Join Scenario
pt
PT_ID PT_NAME----- ------- 1 ptname1 2 ptname2 3 ptname3 : :
wa
WA_ID WA_NAME----- ------- 1 name1 2 name2 3 name3 : :
p
P_ID P_NAME WA_ID PT_ID---- ------ ----- ----- 1 pname1 1 1 2 pname2 2 2 3 pname3 3 3 : : : :
sa
ID NAME WA_ID-- ---- ----- 1 x 1 2 y 2 3 z 3 : : :
48
Right Deep Join Tree
Oracle uses hints internally to force a right deep join in this caseSELECT /*+GATHER_PLAN_STATISTICS */ name FROM sa JOIN wa ON wa.wa_id = sa.wa_id JOIN p ON wa.wa_id = p.wa_id JOIN pt ON pt.pt_id = p.pt_id;
-----------------------------| SELECT STATEMENT | || HASH JOIN | || TABLE ACCESS FULL | SA || HASH JOIN | || TABLE ACCESS FULL | WA || HASH JOIN | || TABLE ACCESS FULL| PT || TABLE ACCESS FULL| P |-----------------------------
SWAP_JOIN_INPUTS(@"SEL$EE94F965" "PT"@"SEL$3")SWAP_JOIN_INPUTS(@"SEL$EE94F965" "WA"@"SEL$1")SWAP_JOIN_INPUTS(@"SEL$EE94F965" "SA"@"SEL$1")
Internally generated hints
49
Left Deep Join Tree
Left deep tree can be forced using hints
-----------------------------| SELECT STATEMENT | || HASH JOIN | || HASH JOIN | || HASH JOIN | || TABLE ACCESS FULL| PT || TABLE ACCESS FULL| P || TABLE ACCESS FULL | WA || TABLE ACCESS FULL | SA |-----------------------------
SELECT /*+GATHER_PLAN_STATISTICS no_swap_join_inputs(wa) no_swap_join_inputs(p) no_swap_join_inputs(pt) no_swap_join_inputs(sa)*/ name FROM sa JOIN wa ON wa.wa_id = sa.wa_id JOIN p ON wa.wa_id = p.wa_id JOIN pt ON pt.pt_id = p.pt_id;
50
Forcing a Bushy Tree
In complex decision support scenarios a bushy tree can be a good plan― Cannot be forced using '(', ')' or ORDERED, LEADING or other 'conventional' hints― Must use inline views and a selection of less well known hints to stop Oracle
merging the views internally
SELECT /*+no_merge(v1) no_merge(v2)*/ nameFROM (SELECT sa.name ,wa.wa_id FROM sa JOIN wa ON wa.wa_id = sa.wa_id) v1 JOIN (SELECT p.wa_id FROM p JOIN pt ON pt.pT_id = p.pT_id) v2ON v1.wa_id = v2.wa_id;
-----------------------------| SELECT STATEMENT | || HASH JOIN | || VIEW | || HASH JOIN | || TABLE ACCESS FULL| PT || TABLE ACCESS FULL| P || VIEW | || HASH JOIN | || TABLE ACCESS FULL| WA || TABLE ACCESS FULL| SA |-----------------------------
51
Oracle12c Join Techniques
ANSI and Oracle Joins
Two-way Outer Joins
Join and Filter Conditions
Chaining on the Outer Join
Hash Join Trees
Anti Joins and Semi Joins
Lateral Joins
Nested Loops Joins
Join Elimination
Adaptive Joins
52
Hash Join Plans
Semi-joins― Often occur with EXISTS and IN subqueries― Used when existence tests are required
Find departments which have employees― Semi-join returns a department only once no matter how many employees
work for it
SELECT * FROM deptWHERE EXISTS (SELECT 'x' FROM emp WHERE deptno = dept.deptno);
53
Right Semi Join
From Oracle 10g, the driving table can be automatically switched― Can depend on size of input rowsets― SWAP_JOIN_INPUTS hint is used internally
• Often used to avoid high memory usage (monitor OMEM with dbms_xplan)
-------------------------------------|Operation |Name |Rows |-------------------------------------|SELECT STATEMENT | |8192 || HASH JOIN RIGHT SEMI| |8192 || VIEW |VW_SQ_1|7168 || TABLE ACCESS FULL |EMP |7168 || TABLE ACCESS FULL |DEPT |8192 |-------------------------------------
-----------------------------------|Operation |Name |Rows|-----------------------------------|SELECT STATEMENT | | 4|| HASH JOIN SEMI | | 4|| TABLE ACCESS FULL |DEPT | 4|| VIEW |VW_SQ_1|7168|| TABLE ACCESS FULL|EMP |7168|-----------------------------------
dept : 8192 rowsemp : 7168 rows
dept : 4 rowsemp : 7168 rows
54
Departments with no Employees
SELECT * FROM deptWHERE deptno NOT IN (SELECT deptno FROM emp);
DEPTNO DNAME LOC------ ---------- ------ 40 OPERATIONS BOSTON
SELECT * FROM dept xWHERE NOT EXISTS (SELECT 1 FROM emp y WHERE y.deptno = x.deptno);
55
No Index and no NOT NULL Constraint on emp.deptno
Oracle Version
NOT IN plan NOT EXISTS plan
8i SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
9i SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT HASH JOIN ANTI TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
10g SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT HASH JOIN ANTI TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
11g SELECT STATEMENT HASH JOIN ANTI NA TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT HASH JOIN ANTI TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
56
NOT NULL constraint on emp.deptno
Oracle Version
NOT IN plan NOT EXISTS plan
8i SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
9i SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT HASH JOIN ANTI TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
10g SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT HASH JOIN ANTI TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
11g SELECT STATEMENT HASH JOIN ANTI SNA TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT HASH JOIN ANTI TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
57
Index on emp.deptno, no NOT NULL constraint
Oracle Version
NOT IN plan NOT EXISTS plan
8i SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT INDEX RANGE SCAN EMP$DEPTNO
9i SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT INDEX RANGE SCAN EMP$DEPTNO
10g SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT NESTED LOOPS ANTI TABLE ACCESS FULL DEPT INDEX RANGE SCAN EMP$DEPTNO
11g SELECT STATEMENT HASH JOIN ANTI NA TABLE ACCESS FULL DEPT TABLE ACCESS FULL EMP
SELECT STATEMENT HASH JOIN ANTI TABLE ACCESS FULL DEPT INDEX FAST FULL SCAN EMP$DEPTNO 58
SELECT STATEMENT NESTED LOOPS ANTI TABLE ACCESS FULL DEPT INDEX RANGE SCAN EMP$DEPTNO
12c
Index and NOT NULL Constraint on emp.deptno
Version NOT IN plan NOT EXISTS plan
8i SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT INDEX RANGE SCAN EMP$DEPTNO
SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT INDEX RANGE SCAN EMP$DEPTNO
9i SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT INDEX FULL SCAN EMP$DEPTNO
SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT INDEX RANGE SCAN EMP$DEPTNO
10g SELECT STATEMENT FILTER TABLE ACCESS FULL DEPT INDEX FULL SCAN EMP$DEPTNO
SELECT STATEMENT NESTED LOOPS ANTI TABLE ACCESS FULL DEPT INDEX RANGE SCAN EMP$DEPTNO
11g SELECT STATEMENT HASH JOIN ANTI SNA TABLE ACCESS FULL DEPT INDEX FULL SCAN EMP$DEPTNO
SELECT STATEMENT NESTED LOOPS ANTI TABLE ACCESS FULL DEPT INDEX RANGE SCAN EMP$DEPTNO
If the column on the right hand side of the condition (emp.deptno) has no NOT NULL constraint, then NA is used — If it is declared NOT NULL, SNA is used, along with an available index
59
Oracle12c Join Techniques
ANSI and Oracle Joins
Two-way Outer Joins
Join and Filter Conditions
Chaining on the Outer Join
Hash Join Trees
Anti Joins and Semi Joins
Lateral Joins
Nested Loops Joins
Join Elimination
Adaptive Joins
60
Lateral Joins
Inline views cannot reference columns outside of the view― Considered to be out of scope
SELECT dname ,enameFROM dept d ,(SELECT ename FROM emp e WHERE e.deptno = d.deptno);
WHERE e.deptno = d.deptno) *ERROR : ORA-00904: "D"."DEPTNO": invalid identifier
61
Lateral views allow such references― Used internally
Similar to correlated subqueries
Lateral Joins in Oracle12c
Need to set an event on Oracle11g― LATERAL keyword can then be used to allow correlation
SELECT dname ,enameFROM dept d ,LATERAL(SELECT ename FROM emp e WHERE e.deptno = d.deptno);
DNAME ENAME-------------- ----------RESEARCH SMITHSALES ALLENSALES WARD : :
ALTER SESSION SET EVENTS '22829 TRACE NAME CONTEXT FOREVER';
Identical execution plan to
equivalent equi-join
62
Lateral Outer Join Syntax – Oracle12c
SELECT dname ,ename ,job ,loc ,salFROM dept ,LATERAL(SELECT ename,job,sal FROM emp WHERE emp.deptno = dept.deptno AND (sal < 1000 OR job = 'ANALYST'))(+);
DNAME ENAME JOB LOC SAL-------------- ---------- --------- ------------- ----------ACCOUNTING NEW YORKRESEARCH SMITH CLERK DALLAS 800RESEARCH SCOTT ANALYST DALLAS 3000RESEARCH FORD ANALYST DALLAS 3000SALES JAMES CLERK CHICAGO 950OPERATIONS BOSTON
63
CROSS APPLY and OUTER APPLY
Attempts to solve compatibility issues with SQL Server migration tools
64
SELECT dname,ename,job,loc,salFROM dept CROSS APPLY (SELECT ename,job,sal FROM emp WHERE emp.deptno = dept.deptno AND (sal < 1000 OR job = 'ANALYST'))
SELECT dname,ename,job,loc,salFROM dept OUTER APPLY (SELECT ename,job,sal FROM emp WHERE emp.deptno = dept.deptno AND (sal < 1000 OR job = 'ANALYST'))
Equivalent Outer Join Plans
-------------------------------------------| Id | Operation | Name | Rows |-------------------------------------------| 0 | SELECT STATEMENT | | 5 ||* 1 | HASH JOIN OUTER | | 5 || 2 | TABLE ACCESS FULL| DEPT | 4 ||* 3 | TABLE ACCESS FULL| EMP | 4 |-------------------------------------------
65
SELECT dname,ename,job,loc,salFROM dept OUTER APPLY (SELECT ename,job,sal FROM emp WHERE emp.deptno = dept.deptno AND (sal < 1000 OR job = 'ANALYST'));
SELECT dname,ename,job,loc,salFROM dept ,LATERAL(SELECT ename,job,sal FROM emp WHERE emp.deptno = dept.deptno AND (sal < 1000 OR job = 'ANALYST'))(+);
SELECT dname,ename,job,loc,salFROM dept, empWHERE emp.deptno(+) = dept.deptnoAND (sal(+) < 1000 OR job(+) = 'ANALYST');
Use of CROSS/OUTER APPLY
When join sets are not known in advance Example purely for illustration : Number of emp rows to join is governed by highest salary in that department
― Note use of subquery in FETCH clause• Can use any appropriate variable or expression
66
SELECT deptno ,empno ,ename ,salFROM dept OUTER APPLY (SELECT empno ,ename ,sal FROM emp WHERE emp.deptno = dept.deptno ORDER BY sal DESC FETCH FIRST (SELECT MAX(sal)/1500 FROM emp WHERE emp.deptno = dept.deptno) ROWS ONLY)ORDER BY dept.deptno;
CROSS APPLY and OUTER APPLY with Table Level Functions
67
CREATE TYPE emp_row_type as OBJECT ( empno VARCHAR2(8), ename VARCHAR2(20), deptno VARCHAR2(20));
CREATE TYPE emp_table_type as TABLE OF emp_row_type;
CREATE OR REPLACE FUNCTION get_all_emps(pi_deptno in number) RETURN emp_table_type PIPELINED ASBEGIN FOR cur IN (SELECT * FROM emp where deptno = pi_deptno) LOOP PIPE ROW(emp_row_type(cur.empno,cur.ename,cur.deptno)); END LOOP; RETURN; END;
Table Function Joins
68
DEPTNO DNAME LOC EMPNO ENAME DEPTNO------ -------------- ------------- -------- -------------------- ------ 10 ACCOUNTING NEW YORK 7782 CLARK 10 : : : : : : 20 RESEARCH DALLAS 7369 SMITH 20 : : : : : : 30 SALES CHICAGO 7900 JAMES 30 : : : : : : 40 OPERATIONS BOSTON
SELECT * FROM dept, TABLE(get_all_emps(dept.deptno)); SELECT * FROM dept CROSS APPLY
TABLE(get_all_emps(dept.deptno));
SELECT * FROM dept, TABLE(get_all_emps(dept.deptno))(+); SELECT * FROM dept OUTER APPLY
TABLE(get_all_emps(dept.deptno));
DEPTNO DNAME LOC EMPNO ENAME DEPTNO------ -------------- ------------- -------- -------------------- ------ 10 ACCOUNTING NEW YORK 7782 CLARK 10 : : : : : : 20 RESEARCH DALLAS 7369 SMITH 20 : : : : : : 30 SALES CHICAGO 7900 JAMES 30 : : : : : :
SELECT * FROM dept JOIN TABLE(get_all_emps(dept.deptno))ON 1 = 1;
SELECT * FROM dept LEFT OUTER JOIN TABLE(get_all_emps(dept.deptno))ON NULL IS NULL;
Oracle12c Join Techniques
ANSI and Oracle Joins
Two-way Outer Joins
Join and Filter Conditions
Chaining on the Outer Join
Hash Join Trees
Anti Joins and Semi Joins
Lateral Joins
Nested Loops Joins
Join Elimination
Adaptive Joins
69
Oracle11g Nested Loops Joins
SELECT /*+ LEADING(e) USE_NL(d)*/ *FROM emp e ,dept dWHERE e.deptno = d.deptno AND e.sal = 3000;
------------------------------------------| SELECT STATEMENT | || NESTED LOOPS | || NESTED LOOPS | | TABLE ACCESS FULL | EMP || INDEX UNIQUE SCAN | PK_DEPT || TABLE ACCESS BY INDEX ROWID| DEPT |------------------------------------------
Batch style operation using an index― ROWIDs collected from an index― Used in a second nested loops style operation against the driven table
• Can reduce physical I/O and improve performance in certain cases
• Could reduce readability of execution plans
70
Reverting to Oracle10g Nested Loops Joins
------------------------------------------| SELECT STATEMENT | || NESTED LOOPS | || TABLE ACCESS FULL | EMP || TABLE ACCESS BY INDEX ROWID| DEPT || INDEX UNIQUE SCAN | PK_DEPT |------------------------------------------
SELECT /*+ LEADING(e) USE_NL(d) NO_NLJ_BATCHING(d)*/ *FROM emp e ,dept dWHERE e.deptno = d.deptno AND e.sal = 3000;ALTER SESSION SET OPTIMIZER_FEATURES_ENABLE = '10.2.0.5';
Use a hint or set a parameter
New undocumented parameter _nlj_batching_enabled (0 or 1)71
Other relevant hintsNLJ_BATCHING()NLJ_PREFETCH()NO_NLJ_PREFETCH()
Oracle12c Join Techniques
ANSI and Oracle Joins
Two-way Outer Joins
Join and Filter Conditions
Chaining on the Outer Join
Hash Join Trees
Anti Joins and Semi Joins
Lateral Joins
Nested Loops Joins
Join Elimination
Adaptive Joins
72
Join Elimination – the Ins and Outs
Some unnecessary joins are eliminated
SELECT e.ename ,e.deptnoFROM emp e ,dept dWHERE e.deptno = d.deptno
------------------------------------------| Id | Operation | Name | Rows |------------------------------------------| 0 | SELECT STATEMENT | | 14 ||* 1 | TABLE ACCESS FULL| EMP | 14 |------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 1 - filter("E"."DEPTNO" IS NOT NULL)
SELECT e.ename ,e.deptnoFROM emp e ,dept dWHERE e.deptno = d.deptno(+)
No access to dept table (or any dept table index) in both cases on 11g Filter is unnecessary if deptno has a NOT NULL constraint
73
Conditions for Join Elimination
Oracle 10g Oracle11g Oracle12c
Inner Join Outer join Inner Join Outer join Inner Join Outer Join
No constraints
Primary key on dept
(or UK) (or UK)
Foreign key on deptno in emp
74
Join Elimination - Antijoins
SELECT e.empno, e.enameFROM emp eWHERE NOT EXISTS (SELECT 1 FROM dept d WHERE d.deptno = e.deptno);
SELECT STATEMENT TABLE ACCESS FULL EMP filter("E"."DEPTNO" IS NOT NULL)
75
SELECT STATEMENT NESTED LOOPS ANTI TABLE ACCESS FULL EMP INDEX UNIQUE SCAN PK_DEPTfilter("E"."DEPTNO"="D”.”DEPTNO”
SELECT STATEMENT FILTER TABLE ACCESS FULL EMPfilter(NULL IS NOT NULL)
Foreign key present
No foreign key
Foreign key and NOT NULL
Dummy filter showing NO access to ANY table
Anti joins can also be eliminated
Join Elimination - Semijoins
SELECT e.empno, e.enameFROM emp eWHERE EXISTS (SELECT 1 FROM dept d WHERE d.deptno = e.deptno);
SELECT STATEMENT TABLE ACCESS FULL EMP filter("E"."DEPTNO" IS NOT NULL)
76
SELECT STATEMENT NESTED LOOPS SEMI TABLE ACCESS FULL EMP INDEX UNIQUE SCAN PK_DEPTfilter("E"."DEPTNO"="D”.”DEPTNO”
SELECT STATEMENT FILTER TABLE ACCESS FULL EMP
Foreign key present
No foreign key
Foreign key and NOT NULL
No filter is necessary
Outer Join Elimination - Implications A view used on the system
― Part of an application
― No access made to dept table even though join is embedded in view• Access is only to the emp table• Does not eliminate access to emp when referencing columns in dept
― Control with hintsELIMINATE_JOIN NO_ELIMINATE_JOIN
― Control with hidden parameter_optimizer_join_elimination_enabled
CREATE VIEW empdept AS SELECT e.ename ,e.job ,e.deptno ,d.dname ,d.locFROM emp e ,dept dWHERE e.deptno = d.deptno(+);
SELECT ename,job FROM empdept;
77
Oracle12c Join Techniques
ANSI and Oracle Joins
Two-way Outer Joins
Join and Filter Conditions
Chaining on the Outer Join
Hash Join Trees
Anti Joins and Semi Joins
Lateral Joins
Nested Loops Joins
Join Elimination
Adaptive Joins
78
Adaptive Joins - Oracle12c Oracle can switch execution plans during actual execution
― Can occur in joins (e.g. emp with dept)
Generates subplans and uses a statistics collector to buffer rows ― Detects if number of rows coming out of a table are more than a threshold value― If so, it switches to an alternative subplan
The new plan becomes the final plan― Subsequent executions will ALWAYS use the final plan
• Statistics collector is bypassed― AUTOTRACE/EXPLAIN will show the initial default plan― dbms_xplan.display_cursor will show the final plan
Designed to optimize when an unexpected number of rows are received― Maybe because of inaccurate statistics
79
Adaptive Joins - Oracle12c
Common switch is from Nested Loops to hash join― Does not work with Sort-Merge
80
Nested Loops Hash Join
Statistics Collector
Table Scan dept
Index Scan emp_dept_fki
Table Scan emp
Final plan : Hash Join
threshold exceeded
Nested Loops Hash Join
Statistics Collector
Table Scan dept
Index Scan emp_dept_fki
Table Scan emp
Default plan : Nested Loops
Adaptive Joins - Tips Must have
― optimizer_adaptive_features = 12.1.0.1 (or higher)― Optimizer_adaptive_reporting_only = FALSE (default)
• If set to TRUE, the optimizer can only report adaptive plans and not use them
New column is_resolved_adaptive_plan in v$sql with values of‘Y’ – plan is the final adaptive plan’N’ – plan is adaptive, but final plan has yet to be decided NULL – plan is not adaptive
dbms_xplan.display_cursor has new arguments, e.g. format => ‘adaptive’― Shows full plan of query including unused steps
• Unused steps marked with ‘-’
81
Undocumented ParametersKSPPINM KSPPSTVL--------------------------------------------- ---------_lm_node_join_opt FALSE_abort_recovery_on_join FALSE_hash_join_enabled TRUE_multi_join_key_table_lookup TRUE_force_hash_join_spill FALSE_always_anti_join CHOOSE_optimizer_null_aware_antijoin TRUE_convert_set_to_join FALSE_push_join_predicate TRUE_push_join_union_view TRUE_push_join_union_view2 TRUE_optimizer_join_sel_sanity_check TRUE_ordered_semijoin TRUE_always_semi_join CHOOSE_full_pwise_join_enabled TRUE_partial_pwise_join_enabled TRUE_index_join_enabled TRUE_improved_outerjoin_card TRUE_cost_equality_semi_join TRUE_new_initial_join_orders TRUE_oneside_colstat_for_equijoins TRUE_gs_anti_semi_join_allowed TRUE_optim_new_default_join_sel TRUE_optimizer_new_join_card_computation TRUE_optimizer_sortmerge_join_enabled TRUE_optimizer_dim_subq_join_sel TRUE_optimizer_join_order_control 3_optimizer_join_elimination_enabled TRUE_optimizer_sortmerge_join_inequality TRUE_selfjoin_mv_duplicates TRUE_optimizer_aw_join_push_enabled TRUE_optimizer_native_full_outer_join FORCE_optimizer_eliminate_filtering_join TRUE_optimizer_join_factorization TRUE_optimizer_outer_join_to_inner TRUE_optimizer_full_outer_join_to_outer TRUE_xsolapi_sql_all_multi_join_non_base_hints_xsolapi_sql_enable_aw_join TRUE
SELECT ksppinm ,ksppstvl FROM x$ksppi I ,x$ksppcv vWHERE v.indx =i.indx AND ksppinm LIKE '%join%';
Around 2750 undocumented parameters on 11g
Around 3968 undocumented parameters on 12c
82
Hints from v$sql_hint
NAME SQL_FEATURE CLASS---------------------------- ---------------------------- ------------------------APPEND QKSFM_CBO APPENDNO_MONITORING QKSFM_ALL NO_MONITORINGNO_SQL_TUNE QKSFM_ALL NO_SQL_TUNEIGNORE_WHERE_CLAUSE QKSFM_ALL IGNORE_WHERE_CLAUSENO_QUERY_TRANSFORMATION QKSFM_TRANSFORMATION NO_QUERY_TRANSFORMATIONOPTIMIZER_FEATURES_ENABLE QKSFM_ALL OPTIMIZER_FEATURES_ENABLGATHER_PLAN_STATISTICS QKSFM_GATHER_PLAN_STATISTICS GATHER_PLAN_STATISTICSIGNORE_OPTIM_EMBEDDED_HINTS QKSFM_ALL IGNORE_OPTIM_EMBEDDED_HITABLE_STATS QKSFM_STATS TABLE_STATSRULE QKSFM_RBO MODECHOOSE QKSFM_CHOOSE MODEFIRST_ROWS QKSFM_FIRST_ROWS MODEORDERED QKSFM_CBO ORDEREDORDERED_PREDICATES QKSFM_CBO ORDERED_PREDICATESPUSH_PRED QKSFM_FILTER_PUSH_PRED PUSH_PREDELIMINATE_JOIN QKSFM_TABLE_ELIM ELIMINATE_JOINNO_ELIMINATE_JOIN QKSFM_TABLE_ELIM ELIMINATE_JOINOUTER_JOIN_TO_INNER QKSFM_OUTER_JOIN_TO_INNER OUTER_JOIN_TO_INNERNO_OUTER_JOIN_TO_INNER QKSFM_OUTER_JOIN_TO_INNER OUTER_JOIN_TO_INNERHASH_AJ QKSFM_CBO ANTIJOINNL_AJ QKSFM_CBO ANTIJOINSEMIJOIN QKSFM_TRANSFORMATION SEMIJOINHASH_SJ QKSFM_CBO SEMIJOINNL_SJ QKSFM_CBO SEMIJOINSTAR QKSFM_STAR_TRANS STARSET_TO_JOIN QKSFM_SET_TO_JOIN SET_TO_JOIN
273 hints on 11g332 hints on 12c
83