Oracle – ANSI Joins

advertisement
Oracle Join Techniques
Carl Dudley
University of Wolverhampton, UK
Oracle ACE Director
carl.dudley@wlv.ac.uk
Carl Dudley – University of Wolverhampton
1
Introduction
Working with Oracle since 1986
Oracle DBA ANSI
- OCP
Oracle7,
8, 9, 10
and
Oracle Joins
Oracle DBA of
the Year
– Joins
2002
Two-way
Outer
Oracle ACE Director
Join and Filter Conditions
Beta tester –Chaining
Oracle8,
10,
11, Join
12
on9,the
Outer
Regular Presenter
at Oracle
Hash Join
Trees Conferences
Consultant and
Anti Trainer
Joins and Semi Joins
Technical Editor
for
a number of Oracle texts
Lateral
Joins
UK Oracle User
Group
Official
Nested
Loops
Joins
Member of IOUC
Join Elimination
Day job – University of Wolverhampton, UK
Carl Dudley – University of Wolverhampton
2
The emp and dept Tables
dept
emp
DEPTNO
-----10
20
30
40
EMPNO
----7934
7782
7839
7369
7876
7566
7902
7788
7900
7521
7654
7844
7499
7698
DNAME
-------------ACCOUNTING
RESEARCH
SALES
OPERATIONS
ENAME
---------MILLER
CLARK
KING
SMITH
ADAMS
JONES
FORD
SCOTT
JAMES
WARD
MARTIN
TURNER
ALLEN
BLAKE
LOC
-------NEW YORK
DALLAS
CHICAGO
BOSTON
JOB
MGR HIREDATE
SAL COMM DEPTNO
--------- ----- ----------- ----- ----- -----CLERK
7782 23-JAN-1982 1300
10
MANAGER
7839 09-JUN-1981 2450
10
PRESIDENT
17-NOV-1981 5000
10
CLERK
7902 17-DEC-1980
800
20
CLERK
7788 12-JAN-1983 1100
20
MANAGER
7839 02-APR-1981 2975
20
ANALYST
7566 03-DEC-1981 3000
20
ANALYST
7566 09-DEC-1982 3000
20
CLERK
7698 03-DEC-1981
950
30
SALESMAN
7698 22-FEB-1981 1250
500
30
SALESMAN
7698 28-SEP-1981 1250 1400
30
SALESMAN
7698 08-SEP-1981 1500
0
30
SALESMAN
7698 20-FEB-1981 1600
300
30
MANAGER
7839 01-MAY-1981 2850
30
Carl Dudley – University of Wolverhampton
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)
Carl Dudley – University of Wolverhampton
4
Inner
UnionJoins
Join – ANSI and Oracle Syntax
Not
in common
use– and
Oracle
Equivalent
ANSI
based
joinshas no support but can be simulated
—SELECT
Numberename,dname,dept.deptno
of columns in each select clause must match
—FROM
Use NULLs
to paddept
out the number of columns
emp JOIN
ON dept.deptno = empa.deptno;
SELECT o.*, NULL,...,NULL FROM orders o
SELECTUNION
ename,dname,deptno
FROM emp
NATURAL
JOIN dept; l.* FROM line_items l
SELECT
NULL,...,NULL,
SELECT ename,dname,deptno
FROM emp
NATURAL JOIN dept
 Expected
output
USING OCOL1
(deptno);
OCOL2 LCOL1 LCOL2
------------— Note the
absence
of the
table ----qualifier for deptno in some of the examples
11111 AAAAA
22222
BBBBB
 Equivalent
Oracle
join
33333 CCCCC
SELECT ename,dname,dept.deptno
88888 XXXXX
FROM emp,dept
99999 YYYYY
WHERE emp.deptno = dept.deptno;
Carl Dudley – University of Wolverhampton
5
The Join Condition
 Join condition (ON clause) must be included
― Helps safeguard against inadvertant cartesian products
SELECT ename,dname,dept.deptno
FROM emp JOIN dept;
ORA-00905: missing keyword
 But join condition does not have to make any sense
— Could cause cartesian products
SELECT ename,dname,dept.deptno
FROM emp JOIN dept
ON emp.empno = emp.empno;
— Oracle join syntax has no protection
Carl Dudley – University of Wolverhampton
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.pname
FROM emp
JOIN dept
ON emp.deptno = dept.deptno
JOIN proj
ON emp.proj_id = proj.proj_id;
Carl Dudley – University of Wolverhampton
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 emp
ON emp.deptno = dept.deptno
FROM emp RIGHT OUTER JOIN dept
ON emp.deptno = dept.deptno
Carl Dudley – University of Wolverhampton
8
Modified Employee Data
empa
EMPNO
----7782
7788
7844
7499
7902
1111
ENAME
-----CLARK
SCOTT
TURNER
ALLEN
FORD
EXTRA
JOB
MGR HIREDATE
SAL COMM DEPTNO
-------- ----- ----------- ---- ----- ------MANAGER
7839 09-JUN-1981 2450
10
ANALYST
7566 19-APR-1987 3000
20
SALESMAN 7698 08-SEP-1981 1500
0
30
SAlESMAN 7698 20-FEB-1981 1600
300
30
ANALYST
7566 03-DEC-1981 3000
20
CEO
01-JAN-1999 500
dept
DEPTNO
------10
20
30
40
DNAME
---------ACCOUNTING
RESEARCH
SALES
OPERATIONS
LOC
-------NEW YORK
DALLAS
CHICAGO
BOSTON
Carl Dudley – University of Wolverhampton
9
RIGHT Outer Joins
SELECT ename,dname,dept.deptno
FROM empa RIGHT OUTER JOIN dept
ON empa.deptno = dept.deptno;
ENAME
------CLARK
SCOTT
TURNER
FORD
ALLEN
DNAME
DEPTNO
------------ -----ACCOUNTING
10
RESEARCH
20
SALES
30
RESEARCH
20
SALES
30
OPERATIONS
40
 Equivalent Oracle join statement
SELECT ename,dname,dept.deptno
FROM empa,dept WHERE dept.deptno = emp.deptno(+);
Carl Dudley – University of Wolverhampton
10
LEFT Outer Joins
SELECT ename,dname,dept.deptno
FROM empa LEFT OUTER JOIN dept
ON empa.deptno = dept.deptno;
ENAME
------CLARK
SCOTT
TURNER
FORD
ALLEN
EXTRA
DNAME
DEPTNO
------------ -----ACCOUNTING
10
RESEARCH
20
SALES
30
RESEARCH
20
SALES
30
 Equivalent Oracle join statement
SELECT ename,dname,dept.deptno
FROM empa, dept WHERE dept.deptno(+) = empa.deptno;
Carl Dudley – University of Wolverhampton
11
FULL Outer Joins
SELECT ename,dname,dept.deptno d_deptno, empa.deptno e_deptno
FROM empa FULL OUTER JOIN dept
ON empa.deptno = dept.deptno;
ENAME
------CLARK
SCOTT
TURNER
FORD
ALLEN
EXTRA
DNAME
D_DEPTNO E_DEPTNO
------------ -------- -------ACCOUNTING
10
10
RESEARCH
20
20
SALES
30
30
RESEARCH
20
20
SALES
30
30
OPERATIONS
All rows included
from both tables
40
 Equivalent (ILLEGAL) Oracle join statement
SELECT ename,dname,dept.deptno,empa.deptno
FROM empa, dept WHERE dept.deptno(+) = empa.deptno(+);
Carl Dudley – University of Wolverhampton
12
FULL OUTER JOIN – Oracle11g
 Oracle now performs a 'NATIVE' full outer join
SELECT ename
,dname
FROM 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
---------------------------------------------------------------
Carl Dudley – University of Wolverhampton
13
FULL OUTER JOIN – Oracle10g
ALTER SESSION SET optimizer_features_enable = '10.2.0.1';
SELECT ename
,dname
FROM empa e FULL OUTER JOIN dept d
ON 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|
-----------------------------------------------------------Carl Dudley – University of Wolverhampton
14
FULL OUTER JOIN – Oracle10g (continued)
 Statement is transformed to a UNION construct
SELECT ename
,dname
FROM empa e
,dept d
WHERE e.deptno = d.deptno(+)
UNION ALL
SELECT null
,dname
FROM dept d2 WHERE NOT EXISTS (SELECT 'x'
FROM empa e2
WHERE e2.deptno = d2.deptno);
― 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
Carl Dudley – University of Wolverhampton
15
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
Carl Dudley – University of Wolverhampton
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
empb
EMPNO
----7782
7788
7844
7499
ENAME
-----CLARK
SCOTT
TURNER
ALLEN
JOB
-------MANAGER
ANALYST
SALESMAN
SAlESMAN
MGR
---7839
7566
7698
7698
HIREDATE
----------09-JUN-1981
19-APR-1987
08-SEP-1981
20-FEB-1981
dept
proj
PROJ_ID
------1
2
3
SAL COMM DEPTNO PROJ_ID
---- ---- ------ ------2450
10
1
3000
20
2
1500
0
30
1
1600 300
30
1
PNAME
--------BPR
MIGRATION
DESIGN
START_DATE
----------01-JUL-2002
12-OCT-2002
01-NOV-2002
DEPTNO
------10
20
30
40
DNAME
---------ACCOUNTING
RESEARCH
SALES
OPERATIONS
Carl Dudley – University of Wolverhampton
LOC
-------NEW YORK
DALLAS
CHICAGO
BOSTON
17
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
(+)
Carl Dudley – University of Wolverhampton
18
ANSI Two-way Outer Joins – Expected result
 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
ENAME
---------ALLEN
TURNER
CLARK
SCOTT
HIREDATE
DEPTNO DNAME
PROJ_ID PNAME
----------- ------ ----------- ------- --------20-FEB-1981
30 SALES
1 BPR
08-SEP-1981
30 SALES
1 BPR
09-JUN-1981
10 ACCOUNTING
1 BPR
19-APR-1987
20 RESEARCH
2 MIGRATION
40 OPERATIONS
3 DESIGN
Carl Dudley – University of Wolverhampton
19
ANSI Two-way Outer Joins – Missing Rows
 Unexpected results?
SELECT ename, hiredate,d.deptno,dname,p.proj_id,pname
FROM dept d LEFT OUTER JOIN empb e
ON e.deptno = d.deptno
RIGHT OUTER JOIN proj p
ON e.proj_id = p.proj_id;
ENAME
---------CLARK
SCOTT
ALLEN
TURNER
HIREDATE
DEPTNO DNAME
PROJ_ID PNAME
----------- ------ ----------- ------- --------09-JUN-1981
10 ACCOUNTING
1 BPR
19-APR-1987
20 RESEARCH
2 MIGRATION
20-FEB-1981
30 SALES
1 BPR
08-SEP-1981
30 SALES
1 BPR
3 DESIGN
Carl Dudley – University of Wolverhampton
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,pname
FROM proj p LEFT OUTER JOIN empb e
ON e.proj_id = p.proj_id
RIGHT OUTER JOIN dept d
ON e.deptno = d.deptno;
ENAME
---------CLARK
SCOTT
TURNER
ALLEN
HIREDATE
DEPTNO DNAME
PROJ_ID PNAME
----------- ------ ----------- ------- --------09-JUN-1981
10 ACCOUNTING
1 BPR
19-APR-1987
20 RESEARCH
2 MIGRATION
08-SEP-1981
30 SALES
1 BPR
20-FEB-1981
30 SALES
1 BPR
40 OPERATIONS
Carl Dudley – University of Wolverhampton
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_id
FROM dept d LEFT OUTER JOIN empb e
ON e.deptno = d.deptno;
ENAME
---------CLARK
SCOTT
TURNER
ALLEN
HIREDATE
DEPTNO DNAME
PROJ_ID
----------- ------ ----------- ------09-JUN-1981
10 ACCOUNTING
1
19-APR-1987
20 RESEARCH
2
08-SEP-1981
30 SALES
1
20-FEB-1981
30 SALES
1
40 OPERATIONS
Carl Dudley – University of Wolverhampton
22
ANSI Two-way Outer Joins – use of FULL
 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
SELECT ename,hiredate,d.deptno,dname,p.proj_id,pname
FROM dept d LEFT OUTER JOIN empb e
ON e.deptno = d.deptno
FULL OUTER JOIN proj p
ON e.proj_id = p.proj_id;
ENAME
---------ALLEN
TURNER
CLARK
SCOTT
HIREDATE
DEPTNO DNAME
PROJ_ID PNAME
----------- ------ ----------- ------- --------20-FEB-1981
30 SALES
1 BPR
08-SEP-1981
30 SALES
1 BPR
09-JUN-1981
10 ACCOUNTING
1 BPR
19-APR-1987
20 RESEARCH
2 MIGRATION
40 OPERATIONS
3 DESIGN
Carl Dudley – University of Wolverhampton
23
Two-way Outer Joins – Oracle Style
 In 11g, Oracle syntax cannot outer join a table to more than one other table
SELECT ename,hiredate,d.deptno,dname,p.proj_id,pname
FROM dept d, empb e, proj p
WHERE e.deptno(+) = d.deptno
AND e.proj_id(+) = p.proj_id;
ORA-01417: a table may be outer joined to at most one other table
Carl Dudley – University of Wolverhampton
24
Two-way Outer Joins – Oracle Style (continued)
 But in Oracle12c, this would be the output
― Cannot be imitated using ANSI syntax
ENAME
---------SCOTT
ALLEN
TURNER
CLARK
HIREDATE
DEPTNO DNAME
PROJ_ID PNAME
----------- ------ ----------- ------- ---------19-APR-1987
20 RESEARCH
2 MIGRATION
20-FEB-1981
30 SALES
1 BPR
08-SEP-1981
30 SALES
1 BPR
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
Carl Dudley – University of Wolverhampton
25
Oracle Outer Joins with Subqueries
 Show each department with its longest serving employee
— Subqueries are not allowed in combination with an outer join condition
SELECT ename, hiredate,d.deptno,dname
FROM dept d,
d LEFT
JOIN emp e
empaOUTER
e
ON
e.deptno
= d.deptno
WHERE
e.deptno(+)
= d.deptno
AND e.hiredate(+)
e.hiredate = (SELECT
MIN(e.hiredate)
= (SELECT
MIN(e.hiredate)
FROM
empempa
e
FROM
e
WHERE
e.deptno
= d.deptno);
WHERE
e.deptno
= d.deptno);
ORA-01799: a column may not be outer-joined to a subquery
 What about ANSI joins?
Carl Dudley – University of Wolverhampton
26
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
Carl Dudley – University of Wolverhampton
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
Carl Dudley – University of Wolverhampton
28
Oracle Join and Filter Conditions
SELECT dept.deptno,dname,ename,job
FROM dept, empa
WHERE empa.deptno(+) = dept.deptno
AND empa.job = 'SALESMAN';
DEPTNO
-----30
30
DNAME
----------SALES
SALES
ENAME
-------TURNER
ALLEN
Filter applied after the join
JOB
-------SALESMAN
SALESMAN
SELECT dept.deptno,dname,ename,job
FROM dept, empa
WHERE empa.deptno(+) = dept.deptno
AND empa.job(+) = 'SALESMAN';
DEPTNO
-----10
20
30
30
40
DNAME
----------ACCOUNTING
RESEARCH
SALES
SALES
OPERATIONS
ENAME
JOB
-------- -------TURNER
ALLEN
Filter applied during the join
— Somewhat awkward syntax
SALESMAN
SALESMAN
Carl Dudley – University of Wolverhampton
29
ANSI Join and Filter Conditions
SELECT dept.deptno,dname,ename,job
FROM dept LEFT OUTER JOIN empa
ON empa.deptno = dept.deptno
WHERE empa.job = 'SALESMAN‘;
DEPTNO
-----30
30
DNAME
---------SALES
SALES
ENAME
-------ALLEN
TURNER
JOB
-------SALESMAN
SALESMAN
Filter applied after the join
— Easier to understand due to
separation of join conditions
from filter conditions
SELECT dept.deptno,dname,ename,job
FROM dept LEFT OUTER JOIN empa
ON empa.deptno = dept.deptno
AND empa.job = 'SALESMAN';
DEPTNO
-----30
30
40
20
10
DNAME
----------SALES
SALES
OPERATIONS
RESEARCH
ACCOUNTING
ENAME
------TURNER
ALLEN
JOB
-------SALESMAN
SALESMAN
Filter applied during the join
Note the three outer joined rows
- one row for each department
having no salesmen
Carl Dudley – University of Wolverhampton
30
Oracle Outer Joins and OR
 Oracle syntax cannot cope
SELECT dname
,ename
,job
,loc
,sal
FROM emp e
,dept d
WHERE e.deptno(+) = d.deptno
AND (sal(+) < 1000 OR loc(+) = 'DALLAS')
ORDER BY dname;
AND (sal(+) < 1000 OR loc(+) = 'DALLAS')
*
ERROR :
ORA-01719:outer join operator (+) not allowed in operand of OR or IN
Carl Dudley – University of Wolverhampton
31
ANSI Outer Joins and OR
 ANSI join handles OR with outer join
SELECT dname
,ename
,job
,loc
,sal
FROM emp e RIGHT OUTER JOIN dept d
ON e.deptno = d.deptno
AND (sal < 1000 OR loc = 'DALLAS')
ORDER BY dname;
DNAME
-------------ACCOUNTING
OPERATIONS
RESEARCH
RESEARCH
RESEARCH
RESEARCH
RESEARCH
SALES
ENAME
JOB
LOC
---------- --------- ------------NEW YORK
BOSTON
ADAMS
CLERK
DALLAS
FORD
ANALYST
DALLAS
JONES
MANAGER
DALLAS
SMITH
CLERK
DALLAS
SCOTT
ANALYST
DALLAS
JAMES
CLERK
CHICAGO
Carl Dudley – University of Wolverhampton
SAL
---1100
3000
2975
800
3000
950
32
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
Carl Dudley – University of Wolverhampton
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
Carl Dudley – University of Wolverhampton
34
Data in the Sample Tables
course
COURSE_ID START_DATE
--------- ---------1001 14-DEC-11
1002 12-JUL-12
1003 20-NOV-12
STUDENT_ID
---------1111
2299
4568
5556
6789
attendance COURSE_ID STUDENT_ID
--------- ---------1001
1111
1002
2299
1003
2299
1002
6789
1003
1111
STUDENT_LNAME student
------------BROWN
ADAMS
COX
TYLER
ROSE
 Two students do not have
any attendances
 All courses and attendances
are related
Carl Dudley – University of Wolverhampton
35
Joining course and attendance
SELECT c.course_id c_course_id
,a.course_id a_course_id
,a.student_id
FROM course c
INNER JOIN attendance a
ON 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 c
ON a.course_id = c.course_id;
C_COURSE_ID A_COURSE_ID A_STUDENT_ID
----------- ----------- -----------1001
1001
1111
1002
1002
2299
1003
1003
2299
1002
1002
6789
1003
1003
1111
 Outer join is completely unnecessary as all rows match
Carl Dudley – University of Wolverhampton
36
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 a
ON s.student_id = a.student_id;
S_STUDENT_ID
-----------1111
2299
2299
6789
1111
4568
5556
S_LNAME A_STUDENT_ID A_COURSE_ID
------- ------------ ----------BROWN
1111
1001
ADAMS
2299
1002
ADAMS
2299
1003
ROSE
6789
1002
BROWN
1111
1003
COX
TYLER
Carl Dudley – University of Wolverhampton
37
Join Three Tables - Inner join 'loses' students
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 a
ON s.student_id = a.student_id INNER JOIN course c
ON c.course_id = a.course_id;
S_STUDENT_ID
-----------1111
2299
2299
6789
1111
S_LNAME A_STUDENT_ID A_COURSE_ID C_COURSE_ID START_DATE
------- ------------ ----------- ----------- ---------BROWN
1111
1001
1001 14-DEC-11
ADAMS
2299
1002
1002 12-JUL-12
ADAMS
2299
1003
1003 20-NOV-12
ROSE
6789
1002
1002 12-JUL-12
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|
-----------------------------------------------
 Rows are lost by the
inner join
 Oracle is smart enough
not to perform the
outer join
Carl Dudley – University of Wolverhampton
38
Chaining on 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 a
ON s.student_id = a.student_id LEFT OUTER JOIN course c
ON c.course_id = a.course_id;
S_STUDENT_ID
-----------1111
2299
2299
6789
1111
4568
5556
S_LNAME A_STUDENT_ID A_COURSE_ID C_COURSE_ID START_DATE
------- ------------ ----------- ----------- ---------BROWN
1111
1001
1001 14-DEC-11
ADAMS
2299
1002
1002 12-JUL-12
ADAMS
2299
1003
1003 20-NOV-12
ROSE
6789
1002
1002 12-JUL-12
BROWN
1111
1003
1003 20-NOV-12
COX
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
Carl Dudley – University of Wolverhampton
39
Avoiding the second 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 course c JOIN attendance a
ON c.course_id = a.course_id RIGHT OUTER JOIN student s
ON s.student_id = a.student_id;
S_STUDENT_ID
-----------1111
2299
2299
6789
1111
4568
5556
S_LNAME A_STUDENT_ID A_COURSE_ID C_COURSE_ID START_DATE
------- ------------ ----------- ----------- ---------BROWN
1111
1001
1001 14-DEC-11
ADAMS
2299
1002
1002 12-JUL-12
ADAMS
2299
1003
1003 20-NOV-12
ROSE
6789
1002
1002 12-JUL-12
BROWN
1111
1003
1003 20-NOV-12
COX
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|
------------------------------------------------
 Inner join performed first
 Outer join preserves all
student rows
Carl Dudley – University of Wolverhampton
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 s
ON s.student_id = a.student_id JOIN course c
ON c.course_id = a.course_id;
S_STUDENT_ID
-----------1111
2299
2299
6789
1111
S_LNAME A_STUDENT_ID A_COURSE_ID C_COURSE_ID START_DATE
------- ------------ ----------- ----------- ---------BROWN
1111
1001
1001 14-DEC-11
ADAMS
2299
1002
1002 12-JUL-12
ADAMS
2299
1003
1003 20-NOV-12
ROSE
6789
1002
1002 12-JUL-12
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
Carl Dudley – University of Wolverhampton
41
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
Carl Dudley – University of Wolverhampton
42
Processing a Hash Join
Build Table (customers)
NAME
CITY
...
SCOTT
BATH
...
PAYNE
YORK
...
FOX
LEEDS
...
SMITH
ELY
...
WOOD
BATH
...
ADAMS
LONDON
...
ORD_ID
NAME
...
1
SMITH
...
2
PAYNE
...
3
FOX
...
4
SCOTT
...
5
WOOD
...
6
ADAMS
...
ADAMS
LONDON
...
FOX
LEEDS
...
PAYNE
YORK
...
SCOTT
BATH
...
WOOD
BATH
...
Hash table
SMITH
ELY ...
Probe Table (orders)
Carl Dudley – University of Wolverhampton
43
Join Trees for T1
T2
T3
T4
 Left deep tree
 Right deep tree
Hash table
built on T4
probed by result
of T1 join T2 join T3
Output of T1 join T2 join T3
probed by T4
Output of T1 join T2
probed by T3
T4
Hash table
built on T1
probed by T2
T1
T3
T2
Hash table
built on T3
probed by result
of T1 join T2
T4
Hash table
built on T2
probed by T1
T3
T2
Carl Dudley – University of Wolverhampton
T1
44
Join Trees for T1
T2
T3
T4 (continued)
 Zig-zag tree
 Bushy tree
T4
T3
T1
T2
T3
T4
T1
Carl Dudley – University of Wolverhampton
T2
45
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
Carl Dudley – University of Wolverhampton
46
Tree Combinations
 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)!
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
 Can Oracle be forced to perform a bushy tree?
Carl Dudley – University of Wolverhampton
47
Four Table Join Scenario
sa
ID
-1
2
3
:
wa
NAME WA_ID
---- ----x
1
y
2
z
3
:
:
WA_ID
----1
2
3
:
WA_NAME
------name1
name2
name3
:
p
pt
P_ID
---1
2
3
:
P_NAME WA_ID PT_ID
------ ----- ----pname1
1
1
pname2
2
2
pname3
3
3
:
:
:
PT_ID
----1
2
3
:
Carl Dudley – University of Wolverhampton
PT_NAME
------ptname1
ptname2
ptname3
:
48
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;
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
----------------------------| SELECT STATEMENT
|
|
| HASH JOIN
|
|
|
TABLE ACCESS FULL | SA |
|
HASH JOIN
|
|
|
TABLE ACCESS FULL | WA |
|
HASH JOIN
|
|
|
TABLE ACCESS FULL| PT |
|
TABLE ACCESS FULL| P |
----------------------------Carl Dudley – University of Wolverhampton
49
Left Deep Join Tree
 Left deep tree can be forced using hints
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;
----------------------------| SELECT STATEMENT
|
|
| HASH JOIN
|
|
|
HASH JOIN
|
|
|
HASH JOIN
|
|
|
TABLE ACCESS FULL| PT |
|
TABLE ACCESS FULL| P |
|
TABLE ACCESS FULL | WA |
|
TABLE ACCESS FULL | SA |
----------------------------Carl Dudley – University of Wolverhampton
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)*/ name
FROM (SELECT sa.name
,wa.wa_id
----------------------------FROM sa JOIN wa
|
|
ON wa.wa_id = sa.wa_id) v1 | SELECT STATEMENT
| HASH JOIN
|
|
JOIN
|
VIEW
|
|
(SELECT p.wa_id
|
HASH JOIN
|
|
FROM p JOIN pt
|
TABLE ACCESS FULL| PT |
ON pt.pT_id = p.pT_id) v2
|
TABLE ACCESS FULL| P |
ON v1.wa_id = v2.wa_id;
|
VIEW
|
|
|
HASH JOIN
|
|
|
TABLE ACCESS FULL| WA |
|
TABLE ACCESS FULL| SA |
----------------------------Carl Dudley – University of Wolverhampton
51
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
Carl Dudley – University of Wolverhampton
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 dept
WHERE EXISTS (SELECT 'x'
FROM emp
WHERE deptno = dept.deptno);
Carl Dudley – University of Wolverhampton
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)
dept : 4 rows
emp : 7168 rows
dept : 8192 rows
emp : 7168 rows
------------------------------------|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|
-----------------------------------
Carl Dudley – University of Wolverhampton
54
Departments with no Employees
SELECT *
FROM dept
WHERE deptno NOT IN (SELECT deptno
FROM emp);
SELECT *
FROM dept x
WHERE NOT EXISTS (SELECT 1
FROM emp y
WHERE y.deptno = x.deptno);
DEPTNO DNAME
LOC
------ ---------- -----40 OPERATIONS BOSTON
Carl Dudley – University of Wolverhampton
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
Carl Dudley – University of Wolverhampton
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
Carl Dudley – University of Wolverhampton
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
Carl Dudley – University of Wolverhampton
58
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
Carl Dudley – University of Wolverhampton
59
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
Carl Dudley – University of Wolverhampton
60
Lateral Joins
 Inline views cannot reference columns outside of the view
― Considered to be out of scope
SELECT dname
,ename
FROM dept d
,(SELECT ename
FROM emp e
WHERE e.deptno = d.deptno);
WHERE e.deptno = d.deptno)
*
ERROR : ORA-00904: "D"."DEPTNO": invalid identifier
 Lateral views allow such references
― Used internally
 Similar to correlated subqueries
Carl Dudley – University of Wolverhampton
61
Lateral Joins in Oracle12c
SELECT dname
,ename
FROM dept d
,LATERAL(SELECT ename
FROM emp e
WHERE e.deptno = d.deptno);
DNAME
-------------RESEARCH
SALES
SALES
:
 Identical execution plan to
equivalent equi-join
ENAME
---------SMITH
ALLEN
WARD
:
 Need to set an event on Oracle11g
― LATERAL keyword can then be used to allow correlation
ALTER SESSION SET EVENTS '22829 TRACE NAME CONTEXT FOREVER';
Carl Dudley – University of Wolverhampton
62
Lateral Outer Join Syntax
SELECT dname
,ename
,job
,loc
,sal
FROM dept
,LATERAL(SELECT ename,job,sal
FROM emp
WHERE emp.deptno = dept.deptno
AND (sal < 1000 OR job = 'ANALYST'))(+);
DNAME
-------------ACCOUNTING
RESEARCH
RESEARCH
RESEARCH
SALES
OPERATIONS
ENAME
JOB
LOC
SAL
---------- --------- ------------- ---------NEW YORK
SMITH
CLERK
DALLAS
800
SCOTT
ANALYST
DALLAS
3000
FORD
ANALYST
DALLAS
3000
JAMES
CLERK
CHICAGO
950
BOSTON
Carl Dudley – University of Wolverhampton
63
CROSS APPLY and OUTER APPLY
 Compatibility issues with SQL Server migration tools
SELECT dname,ename,job,loc,sal
FROM 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,sal
FROM dept
OUTER APPLY (SELECT ename,job,sal
FROM emp
WHERE emp.deptno = dept.deptno
AND (sal < 1000 OR job = 'ANALYST'))
Carl Dudley – University of Wolverhampton
64
Equivalent Outer Join Plans
SELECT dname,ename,job,loc,sal
FROM 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,sal
FROM dept, emp
WHERE emp.deptno(+) = dept.deptno
AND (sal(+) < 1000
OR job(+) = 'ANALYST')
SELECT dname,ename,job,loc,sal
FROM dept
,LATERAL(SELECT ename,job,sal
FROM emp
WHERE emp.deptno = dept.deptno
AND (sal < 1000
OR job = 'ANALYST'))(+);
------------------------------------------| 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 |
------------------------------------------Carl Dudley – University of Wolverhampton
65
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
SELECT deptno
,empno
,ename
,sal
FROM 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;
Carl Dudley – University of Wolverhampton
66
CROSS/OUTER APPLY with Table level functions
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 AS
BEGIN
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;
Carl Dudley – University of Wolverhampton
67
Table Function Joins
SELECT * FROM dept,
TABLE(get_all_emps(dept.deptno));
DEPTNO
-----10
:
20
:
30
:
DNAME
-------------ACCOUNTING
:
RESEARCH
:
SALES
:
LOC
------------NEW YORK
:
DALLAS
:
CHICAGO
:
EMPNO
-------7782
:
7369
:
7900
:
SELECT * FROM dept,
TABLE(get_all_emps(dept.deptno))(+);
DEPTNO
-----10
:
20
:
30
:
40
DNAME
-------------ACCOUNTING
:
RESEARCH
:
SALES
:
OPERATIONS
LOC
------------NEW YORK
:
DALLAS
:
CHICAGO
:
BOSTON
EMPNO
-------7782
:
7369
:
7900
:
SELECT * FROM dept CROSS APPLY
TABLE(get_all_emps(dept.deptno));
ENAME
-------------------CLARK
:
SMITH
:
JAMES
:
DEPTNO
-----10
:
20
:
30
:
SELECT * FROM dept OUTER APPLY
TABLE(get_all_emps(dept.deptno));
ENAME
-------------------CLARK
:
SMITH
:
JAMES
:
Carl Dudley – University of Wolverhampton
DEPTNO
-----10
:
20
:
30
:
68
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
Carl Dudley – University of Wolverhampton
69
Oracle11g Nested Loops Joins
SELECT /*+ LEADING(e) USE_NL(d)*/ *
FROM emp e
,dept d
WHERE e.deptno = d.deptno
AND e.sal = 3000;
 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
-----------------------------------------| SELECT STATEMENT
|
|
| NESTED LOOPS
|
|
|
NESTED LOOPS
|
|
TABLE ACCESS FULL
| EMP
|
|
INDEX UNIQUE SCAN
| PK_DEPT |
|
TABLE ACCESS BY INDEX ROWID| DEPT
|
------------------------------------------
• Could reduce readability of execution plans
Carl Dudley – University of Wolverhampton
70
Reverting to Oracle10g Nested Loops Joins
 Use a hint or set a parameter
SELECT /*+ LEADING(e) USE_NL(d) NO_NLJ_BATCHING(d)*/ *
FROM emp e
,dept d
WHERE e.deptno = d.deptno
AND e.sal = 3000;
ALTER SESSION SET
OPTIMIZER_FEATURES_ENABLE = '10.2.0.5';
-----------------------------------------| SELECT STATEMENT
|
|
| NESTED LOOPS
|
|
|
TABLE ACCESS FULL
| EMP
|
|
TABLE ACCESS BY INDEX ROWID| DEPT
|
|
INDEX UNIQUE SCAN
| PK_DEPT |
------------------------------------------
Other relevant hints
NLJ_BATCHING()
NLJ_PREFETCH()
NO_NLJ_PREFETCH()
New undocumented parameter _nlj_batching_enabled (0 or 1)
Carl Dudley – University of Wolverhampton
71
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
Carl Dudley – University of Wolverhampton
72
Join Elimination – the Ins and Outs
 Some unnecessary joins are eliminated
SELECT e.ename
,e.deptno
FROM emp e
,dept d
WHERE e.deptno = d.deptno
SELECT e.ename
,e.deptno
FROM emp e
,dept d
WHERE 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)
 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
Carl Dudley – University of Wolverhampton
73
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




Carl Dudley – University of Wolverhampton
74
Join Elimination - Antijoins
 Anti joins can also be eliminated
SELECT e.empno, e.ename
FROM emp e
WHERE NOT EXISTS (SELECT 1
FROM dept d
WHERE d.deptno = e.deptno);
SELECT STATEMENT
NESTED LOOPS ANTI
TABLE ACCESS FULL EMP
INDEX UNIQUE SCAN PK_DEPT
No foreign key
filter("E"."DEPTNO"="D”.”DEPTNO”
SELECT STATEMENT
TABLE ACCESS FULL EMP
Foreign key present
filter("E"."DEPTNO" IS NOT NULL)
SELECT STATEMENT
FILTER
TABLE ACCESS FULL EMP
filter(NULL IS NOT NULL)
Foreign key and NOT NULL
Dummy filter showing NO access to ANY table
Carl Dudley – University of Wolverhampton
75
Join Elimination - Semijoins
SELECT e.empno, e.ename
FROM emp e
WHERE EXISTS (SELECT 1
FROM dept d
WHERE d.deptno = e.deptno);
SELECT STATEMENT
NESTED LOOPS SEMI
TABLE ACCESS FULL EMP
INDEX UNIQUE SCAN PK_DEPT
No foreign key
filter("E"."DEPTNO"="D”.”DEPTNO”
SELECT STATEMENT
TABLE ACCESS FULL EMP
Foreign key present
filter("E"."DEPTNO" IS NOT NULL)
SELECT STATEMENT
FILTER
TABLE ACCESS FULL EMP
Foreign key and NOT NULL
No filter is necessary
Carl Dudley – University of Wolverhampton
76
Outer Join Elimination - Implications
 A view used on the system
― Part of an application
CREATE VIEW empdept AS
SELECT e.ename
,e.job
,e.deptno
,d.dname
,d.loc
FROM emp e
,dept d
WHERE e.deptno = d.deptno(+);
SELECT ename,job FROM empdept;
― 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
Carl Dudley – University of Wolverhampton
77
Undocumented Parameters
KSPPINM
--------------------------------------------_lm_node_join_opt
_abort_recovery_on_join
_hash_join_enabled
_multi_join_key_table_lookup
_force_hash_join_spill
_always_anti_join
_optimizer_null_aware_antijoin
_convert_set_to_join
_push_join_predicate
_push_join_union_view
_push_join_union_view2
_optimizer_join_sel_sanity_check
_ordered_semijoin
_always_semi_join
_full_pwise_join_enabled
_partial_pwise_join_enabled
_index_join_enabled
_improved_outerjoin_card
_cost_equality_semi_join
_new_initial_join_orders
_oneside_colstat_for_equijoins
_gs_anti_semi_join_allowed
_optim_new_default_join_sel
_optimizer_new_join_card_computation
_optimizer_sortmerge_join_enabled
_optimizer_dim_subq_join_sel
_optimizer_join_order_control
_optimizer_join_elimination_enabled
_optimizer_sortmerge_join_inequality
_selfjoin_mv_duplicates
_optimizer_aw_join_push_enabled
_optimizer_native_full_outer_join
_optimizer_eliminate_filtering_join
_optimizer_join_factorization
_optimizer_outer_join_to_inner
_optimizer_full_outer_join_to_outer
_xsolapi_sql_all_multi_join_non_base_hints
_xsolapi_sql_enable_aw_join
KSPPSTVL
--------FALSE
FALSE
TRUE
TRUE
FALSE
CHOOSE
TRUE
FALSE
TRUE
TRUE
TRUE
TRUE
TRUE
CHOOSE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
3
TRUE
TRUE
TRUE
TRUE
FORCE
TRUE
TRUE
TRUE
TRUE
SELECT ksppinm
,ksppstvl
FROM x$ksppi I
,x$ksppcv v
WHERE v.indx =i.indx
AND ksppinm LIKE '%join%';
 Around 2750 undocumented
parameters on 11g
TRUE
Carl Dudley – University of Wolverhampton
78
Hints from v$sql_hint
NAME
---------------------------APPEND
NO_MONITORING
NO_SQL_TUNE
IGNORE_WHERE_CLAUSE
NO_QUERY_TRANSFORMATION
OPTIMIZER_FEATURES_ENABLE
GATHER_PLAN_STATISTICS
IGNORE_OPTIM_EMBEDDED_HINTS
TABLE_STATS
RULE
CHOOSE
FIRST_ROWS
ORDERED
ORDERED_PREDICATES
PUSH_PRED
ELIMINATE_JOIN
NO_ELIMINATE_JOIN
OUTER_JOIN_TO_INNER
NO_OUTER_JOIN_TO_INNER
HASH_AJ
NL_AJ
SEMIJOIN
HASH_SJ
NL_SJ
STAR
SET_TO_JOIN
SQL_FEATURE
---------------------------QKSFM_CBO
QKSFM_ALL
QKSFM_ALL
QKSFM_ALL
QKSFM_TRANSFORMATION
QKSFM_ALL
QKSFM_GATHER_PLAN_STATISTICS
QKSFM_ALL
QKSFM_STATS
QKSFM_RBO
QKSFM_CHOOSE
QKSFM_FIRST_ROWS
QKSFM_CBO
QKSFM_CBO
QKSFM_FILTER_PUSH_PRED
QKSFM_TABLE_ELIM
QKSFM_TABLE_ELIM
QKSFM_OUTER_JOIN_TO_INNER
QKSFM_OUTER_JOIN_TO_INNER
QKSFM_CBO
QKSFM_CBO
QKSFM_TRANSFORMATION
QKSFM_CBO
QKSFM_CBO
QKSFM_STAR_TRANS
QKSFM_SET_TO_JOIN
CLASS
-----------------------APPEND
NO_MONITORING
NO_SQL_TUNE
IGNORE_WHERE_CLAUSE
NO_QUERY_TRANSFORMATION
OPTIMIZER_FEATURES_ENABL
GATHER_PLAN_STATISTICS
IGNORE_OPTIM_EMBEDDED_HI
TABLE_STATS
MODE
MODE
MODE
ORDERED
ORDERED_PREDICATES
PUSH_PRED
ELIMINATE_JOIN
ELIMINATE_JOIN
OUTER_JOIN_TO_INNER
OUTER_JOIN_TO_INNER
ANTIJOIN
ANTIJOIN
273 hints on
SEMIJOIN
SEMIJOIN
SEMIJOIN
STAR
SET_TO_JOIN
Carl Dudley – University of Wolverhampton
79
11g
Oracle Join Techniques
Carl Dudley
University of Wolverhampton, UK
Oracle ACE Director
carl.dudley@wlv.ac.uk
Carl Dudley – University of Wolverhampton
80
Download