Нет, он не строит декартово произведение двух таблиц для внутреннего или внешнего соединения.
База данных использует декартово объединение, когда одна или несколько таблиц не имеют условий соединения с какими-либо другими таблицами в операторе. " Руководство по настройке базы данных SQL
Итак, в вашем примере это декартово соединение, только если предложение 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;
Обычно используется один из трех методов соединения, которые объясняются в том же документе .
В вашем случае для внутреннего соединения используется "hash join":
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"(+))