Carl Dudley – University of Wolverhampton 1 Oracle Join Techniques Carl Dudley University of...
-
Upload
amberlynn-whitehead -
Category
Documents
-
view
226 -
download
0
Transcript of Carl Dudley – University of Wolverhampton 1 Oracle Join Techniques Carl Dudley University of...
Carl Dudley – University of Wolverhampton 1
Oracle Join Techniques
Carl Dudley
University of Wolverhampton, UK
Oracle ACE Director
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
2Carl Dudley – University of Wolverhampton
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
Day job – University of Wolverhampton, UK
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
3Carl Dudley – University of Wolverhampton
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)
4Carl Dudley – University of Wolverhampton
Inner Joins – ANSI and Oracle Syntax
Equivalent ANSI – based joins
SELECT ename,dname,dept.deptnoFROM emp JOIN dept ON dept.deptno = empa.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;
5Carl Dudley – University of Wolverhampton
Not in common use and Oracle has no support but can be simulated
— Number of columns in each select clause must match
— Use NULLs to pad out the number of columns
Union Join
SELECT o.*, NULL,...,NULL FROM orders oUNION SELECT NULL,...,NULL, l.* FROM line_items l
OCOL1 OCOL2 LCOL1 LCOL2----- ----- ----- -----11111 AAAAA22222 BBBBB33333 CCCCC 88888 XXXXX 99999 YYYYY
Expected output
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;
6Carl Dudley – University of Wolverhampton
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;
7Carl Dudley – University of Wolverhampton
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 emp
ON emp.deptno = dept.deptno
FROM emp RIGHT OUTER JOIN dept
ON emp.deptno = dept.deptno
8Carl Dudley – University of Wolverhampton
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
9Carl Dudley – University of Wolverhampton
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
10Carl Dudley – University of Wolverhampton
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
11Carl Dudley – University of Wolverhampton
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
12Carl Dudley – University of Wolverhampton
FULL OUTER JOIN – Oracle11g
Oracle now performs a 'NATIVE' full outer join
SELECT 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---------------------------------------------------------------
13Carl Dudley – University of Wolverhampton
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';
14Carl Dudley – University of Wolverhampton
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);
15Carl Dudley – University of Wolverhampton
Oracle 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
16Carl Dudley – University of Wolverhampton
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
17Carl Dudley – University of Wolverhampton
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
(+) (+)
18Carl Dudley – University of Wolverhampton
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
19Carl Dudley – University of Wolverhampton
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
20Carl Dudley – University of Wolverhampton
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
21Carl Dudley – University of Wolverhampton
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
22Carl Dudley – University of Wolverhampton
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
23Carl Dudley – University of Wolverhampton
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;
24Carl Dudley – University of Wolverhampton
Two-way Outer Joins – Oracle Style (continued)
But in Oracle12c, this would be the output― Cannot be imitated using ANSI syntax
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
25Carl Dudley – University of Wolverhampton
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?
26Carl Dudley – University of Wolverhampton
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);
Oracle 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
27Carl Dudley – University of Wolverhampton
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
28Carl Dudley – University of Wolverhampton
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
29Carl Dudley – University of Wolverhampton
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
30Carl Dudley – University of Wolverhampton
Oracle Outer Joins and OR
Oracle syntax cannot cope
SELECT dname ,ename ,job ,loc ,salFROM emp e ,dept dWHERE e.deptno(+) = d.deptnoAND (sal(+) < 1000 OR loc(+) = 'DALLAS')ORDER BY dname;
31Carl Dudley – University of Wolverhampton
AND (sal(+) < 1000 OR loc(+) = 'DALLAS') *ERROR :ORA-01719:outer join operator (+) not allowed in operand of OR or IN
ANSI Outer Joins and OR
ANSI join handles OR with outer join
SELECT dname ,ename ,job ,loc ,salFROM emp e RIGHT OUTER JOIN dept dON e.deptno = d.deptnoAND (sal < 1000 OR loc = 'DALLAS')ORDER BY dname;
DNAME ENAME JOB LOC SAL-------------- ---------- --------- ------------- ----ACCOUNTING NEW YORKOPERATIONS BOSTONRESEARCH ADAMS CLERK DALLAS 1100RESEARCH FORD ANALYST DALLAS 3000RESEARCH JONES MANAGER DALLAS 2975RESEARCH SMITH CLERK DALLAS 800RESEARCH SCOTT ANALYST DALLAS 3000SALES JAMES CLERK CHICAGO 950
32Carl Dudley – University of Wolverhampton
Oracle 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
33Carl Dudley – University of Wolverhampton
'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
34Carl Dudley – University of Wolverhampton
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
35Carl Dudley – University of Wolverhampton
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;
36Carl Dudley – University of Wolverhampton
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
37Carl Dudley – University of Wolverhampton
Join Three Tables - Inner join 'loses' students
Rows are lost by the 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|-----------------------------------------------
38Carl Dudley – University of Wolverhampton
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 performed between attendance and course when not strictly necessary
39Carl Dudley – University of Wolverhampton
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|------------------------------------------------
40Carl Dudley – University of Wolverhampton
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
41Carl Dudley – University of Wolverhampton
Oracle 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
42Carl Dudley – University of Wolverhampton
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)
43Carl Dudley – University of Wolverhampton
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
44Carl Dudley – University of Wolverhampton
Bushy tree
T2T1 T3 T4 T2T1
T3
T4
Zig-zag tree
45Carl Dudley – University of Wolverhampton
Join Trees for T1 T2 T3 T4 (continued)
Summary of 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
46Carl Dudley – University of Wolverhampton
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― 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?
47Carl Dudley – University of Wolverhampton
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 : : :
48Carl Dudley – University of Wolverhampton
Right Deep Join Tree
Oracle uses hints internally to force a right deep join in this case
SELECT /*+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
49Carl Dudley – University of Wolverhampton
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;
50Carl Dudley – University of Wolverhampton
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 |-----------------------------
51Carl Dudley – University of Wolverhampton
Oracle 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
52Carl Dudley – University of Wolverhampton
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);
53Carl Dudley – University of Wolverhampton
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 rows
emp : 7168 rows
dept : 4 rows
emp : 7168 rows
54Carl Dudley – University of Wolverhampton
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);
55Carl Dudley – University of Wolverhampton
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
56Carl Dudley – University of Wolverhampton
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
57Carl Dudley – University of Wolverhampton
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 58Carl Dudley – University of Wolverhampton
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
59Carl Dudley – University of Wolverhampton
Oracle 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
60Carl Dudley – University of Wolverhampton
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
61Carl Dudley – University of Wolverhampton
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
62Carl Dudley – University of Wolverhampton
Lateral Outer Join Syntax
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
63Carl Dudley – University of Wolverhampton
CROSS APPLY and OUTER APPLY
Compatibility issues with SQL Server migration tools
Carl Dudley – University of Wolverhampton 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 |-------------------------------------------
65Carl Dudley – University of Wolverhampton
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
Carl Dudley – University of Wolverhampton 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/OUTER APPLY with Table level functions
Carl Dudley – University of Wolverhampton 67
CREATE TYPE emp_row_type as OBJECT ( empno VARCHA2R(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
Carl Dudley – University of Wolverhampton 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 : : : : : :
Oracle 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
69Carl Dudley – University of Wolverhampton
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
70Carl Dudley – University of Wolverhampton
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)71Carl Dudley – University of Wolverhampton
Other relevant hintsNLJ_BATCHING()NLJ_PREFETCH()NO_NLJ_PREFETCH()
Oracle 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
72Carl Dudley – University of Wolverhampton
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
73Carl Dudley – University of Wolverhampton
Conditions for Join Elimination
Oracle 10g Oracle11g
Inner Join Outer join Inner Join Outer join
No constraints Primary key on dept
(or UK)
Foreign key on deptno in emp
74Carl Dudley – University of Wolverhampton
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)
75Carl Dudley – University of Wolverhampton
SELECT STATEMENT NESTED LOOPS ANTI TABLE ACCESS FULL EMP INDEX UNIQUE SCAN PK_DEPT
filter("E"."DEPTNO"="D”.”DEPTNO”
SELECT STATEMENT FILTER TABLE ACCESS FULL EMP
filter(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)
76Carl Dudley – University of Wolverhampton
SELECT STATEMENT NESTED LOOPS SEMI TABLE ACCESS FULL EMP INDEX UNIQUE SCAN PK_DEPT
filter("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 hints
ELIMINATE_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;
77Carl Dudley – University of Wolverhampton
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
78Carl Dudley – University of Wolverhampton
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 11g
79Carl Dudley – University of Wolverhampton
Carl Dudley – University of Wolverhampton 80
Oracle Join Techniques
Carl Dudley
University of Wolverhampton, UK
Oracle ACE Director