阅读Karen Morten的“ Pro Oracle SQL”,第9页“ FROM子句”说
按以下顺序处理联接
- 交叉加入
- 内部加入
- 外部加入
那么,Oracle是否总是针对联接所涉及的两个表创建笛卡尔积,无论是内部联接还是外部联接?
表A的值是1到10(唯一),表B的值是(2,4,6,8)
内部加入:
select a.a1, b.b1 from a,b where a.a1 = b.b1;
外部加入:
select a.a1, b.b1 from a,b where a.a1 = (+) b.b1;
根据...形成结果
答案 0 :(得分:1)
否,它不会为内部或外部联接建立两个表的笛卡尔积。
当一个或多个表对语句中的任何其他表没有任何连接条件时,数据库将使用笛卡尔连接。” Database SQL Tuning Guide
因此,在您的示例中,仅在where子句为空的情况下才进行笛卡尔联接:
EXPLAIN PLAN FOR
SELECT a.a1, b.b1 FROM a,b;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 40 | 240 | 10 (0)| 00:00:01 |
| 1 | MERGE JOIN CARTESIAN| | 40 | 240 | 10 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL | B | 4 | 12 | 3 (0)| 00:00:01 |
| 3 | BUFFER SORT | | 10 | 30 | 7 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL | A | 10 | 30 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------
SELECT a.a1, b.b1 FROM a,b;
通常使用三种连接方法之一,在同一document中对此进行了解释。
在您的情况下,它对内部联接使用“哈希联接”:
EXPLAIN PLAN FOR
SELECT a.a1, b.b1 FROM a,b WHERE a.a1 = b.b1;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 24 | 6 (0)| 00:00:01 |
|* 1 | HASH JOIN | | 4 | 24 | 6 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL| B | 4 | 12 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| A | 10 | 30 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("A"."A1"="B"."B1")
以及用于外部联接的“外部哈希联接”:
EXPLAIN PLAN FOR
SELECT a.a1, b.b1 FROM a,b WHERE a.a1 = b.b1(+);
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 60 | 6 (0)| 00:00:01 |
|* 1 | HASH JOIN OUTER | | 10 | 60 | 6 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL| A | 10 | 30 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| B | 4 | 12 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("A"."A1"="B"."B1"(+))