Как вы наблюдаете это поведение? Вы случайно не выполняете INSERT
или CREATE TABLE
? Это объяснило бы ваше наблюдение, потому что в конце все строки обязательны.
Также, если ваш клиент установил опцию fetch all rows
, это можно наблюдать.
Но в обычном случае, когда клиент интересуется несколькими первыми строками Oracle быстро возвращает первые доступные (размер массива) строки из первого соединения , игнорируя второе.
Вы можете выполнить этот маленький Геданкенский эксперимент :
create table test1 as
select rownum id,
lpad('x',1023,'X') pad
from dual connect by level <= 1000000;
Создать аналог таблицы с 2 по 4.
Теперь запустите ваш запрос (адаптированный к правильному синтаксису)
SELECT * FROM TEST1 CROSS JOIN TEST2
UNION ALL
SELECT * FROM TEST3 CROSS JOIN TEST4;
Это возвращает для моей первой страницы в SQL Developer примерно через 30 секунд, что как-то опровергает вашу заявку.
Простое вычисление необходимого пространства TEMP для двух 10 ** 6 * 10 ** 6 декартовых соединений со строкой длиной 1K - это намного выше моей конфигурации TEMP.
Один из возможных способов узнать, что на самом деле делает Oracle , - выполнить запрос с подсказкой /*+ gather_plan_statistics */
.
Чем получить SQL_ID
оператора и проверить фактические строки A-Rows
в плане
select * from table(dbms_xplan.display_cursor('a9y62gxagups6',null,'ALLSTATS LAST'));
SQL_ID a9y62gxagups6, child number 0
-------------------------------------
SELECT /*+ gather_plan_statistics */ * FROM TEST1 CROSS JOIN TEST2
UNION ALL SELECT * FROM TEST3 CROSS JOIN TEST4
Plan hash value: 1763392637
--------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | Writes | OMem | 1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 50 |00:00:28.52 | 166K| 166K| 142K| | | |
| 1 | UNION-ALL | | 1 | | 50 |00:00:28.52 | 166K| 166K| 142K| | | |
| 2 | MERGE JOIN CARTESIAN| | 1 | 1000G| 50 |00:00:28.52 | 166K| 166K| 142K| | | |
| 3 | TABLE ACCESS FULL | TEST1 | 1 | 1000K| 1 |00:00:00.02 | 4 | 28 | 0 | | | |
| 4 | BUFFER SORT | | 1 | 1000K| 50 |00:00:28.49 | 166K| 166K| 142K| 1255M| 11M| 97M (0)|
| 5 | TABLE ACCESS FULL | TEST2 | 1 | 1000K| 1000K|00:00:03.66 | 166K| 166K| 0 | | | |
| 6 | MERGE JOIN CARTESIAN| | 0 | 1000G| 0 |00:00:00.01 | 0 | 0 | 0 | | | |
| 7 | TABLE ACCESS FULL | TEST3 | 0 | 1000K| 0 |00:00:00.01 | 0 | 0 | 0 | | | |
| 8 | BUFFER SORT | | 0 | 1000K| 0 |00:00:00.01 | 0 | 0 | 0 | 1103M| 10M| |
| 9 | TABLE ACCESS FULL | TEST4 | 0 | 1000K| 0 |00:00:00.01 | 0 | 0 | 0 | | | |
--------------------------------------------------------------------------------------------------------------------------------------
Вы видите, что Оракул
1) полное сканирование таблицы 2 (строка 5)
2) получить одну строку из таблицы 1 (строка 3)
3) вернуться к первому разряду 50 рядов (ряд 0)
4) таблицы 3 и 4 не привязаны (строки 7 и 9)
Вы можете просто адаптировать пример к своему внутреннему соединению, чтобы увидеть похожие результаты.