
There isn’t any.
The author had stated that the classic syntax “is generating
a cartesian product, and then filtering the result set with a predicate.”
The reality is that both the classic and the ANSI syntax
create exactly the same plan. Running
both I then looked at V$SQL to see the plan created:
SQL> SELECT *
2 FROM
emp,
3 dept
4 WHERE
emp.deptno = dept.deptno
5 AND dept.dname = 'SALES';
SQL> SELECT *
2 FROM
emp
3 join dept USING(deptno)
4 WHERE
dname = 'SALES';
SQL> select sql_id, child_number,plan_hash_value,
sql_text from v$sql where sql_text like 'SELECT * FROM emp%'
SQL_ID
CHILD_NUMBER PLAN_HASH_VALUE
------------- --------------- ---------------
SQL_TEXT
----------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
4ug91aycb85jh 0 1688427947
SELECT * FROM
emp join dept USING(deptno)
WHERE dname = 'SALES'
6snrnnz2qfwms 0 1688427947
SELECT * FROM
emp, dept WHERE emp.deptno = dept.deptno AND dept.dname = 'SALES'
Notice they both have the exact same PLAN_HASH_VALUE, this
means they both use the exact same plan:
SQL> SELECT PLAN_TABLE_OUTPUT
2 FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR
3 ('4ug91aycb85jh',0,'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
SQL_ID
4ug91aycb85jh, child number 0
-------------------------------------
SELECT * FROM
emp join dept USING(deptno)
WHERE dname =
'SALES'
Plan hash value: 1688427947
-------------------------------------------------------------------------------------------------------
| Id |
Operation | Name | Starts | E-Rows | A-Rows | A-Time
| Buffers |
-------------------------------------------------------------------------------------------------------
| 0 | SELECT
STATEMENT | |
1 | | 6 |00:00:00.01 | 12 |
| 1 | NESTED LOOPS | | 1 |
| 6 |00:00:00.01 | 12 |
| 2 | NESTED LOOPS | | 1 |
4 | 6 |00:00:00.01 | 10
|
|* 3 | TABLE ACCESS FULL | DEPT |
1 | 1 | 1 |00:00:00.01 | 8 |
|* 4 | INDEX RANGE SCAN | EMP_DEPT_IDX | 1 |
5 | 6 |00:00:00.01 | 2 |
| 5 | TABLE ACCESS BY INDEX ROWID| EMP |
6 | 4 | 6 |00:00:00.01 | 2 |
-------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 -
filter("DEPT"."DNAME"='SALES')
4 -
access("EMP"."DEPTNO"="DEPT"."DEPTNO")
filter("EMP"."DEPTNO" IS NOT NULL)
SQL> SELECT PLAN_TABLE_OUTPUT
2 FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR
3 ('6snrnnz2qfwms',0,'ALLSTATS LAST'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
SQL_ID
6snrnnz2qfwms, child number 0
-------------------------------------
SELECT * FROM
emp, dept WHERE emp.deptno = dept.deptno
AND dept.dname = 'SALES'
Plan hash value: 1688427947
-------------------------------------------------------------------------------------------------------
| Id |
Operation | Name | Starts | E-Rows | A-Rows | A-Time
| Buffers |
-------------------------------------------------------------------------------------------------------
| 0 | SELECT
STATEMENT | | 1 |
| 6 |00:00:00.01 | 12 |
| 1 | NESTED LOOPS | | 1 |
| 6 |00:00:00.01 | 12 |
| 2 | NESTED LOOPS | | 1 |
4 | 6 |00:00:00.01 | 10 |
|* 3 | TABLE ACCESS FULL | DEPT |
1 | 1 | 1 |00:00:00.01 | 8 |
|* 4 | INDEX RANGE SCAN | EMP_DEPT_IDX | 1 |
5 | 6 |00:00:00.01 | 2 |
| 5 | TABLE ACCESS BY INDEX ROWID| EMP |
6 | 4 | 6 |00:00:00.01 | 2 |
-------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 -
filter("DEPT"."DNAME"='SALES')
4 -
access("EMP"."DEPTNO"="DEPT"."DEPTNO")
filter("EMP"."DEPTNO" IS NOT NULL)
Is this going to be true for all statement? I certainly doubt it, there are always
exceptions. My inclination is that
switching between the two syntax types is likely to produce the same plan more
times than not. Of course a test is worth 1000 opinions.
Database used for this test was:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Running on Windows 7 Professional.
No comments:
Post a Comment