Ваш запрос выполняет три задачи:
1) выборки данных для обоих подмножеств (12 и 14)
2) Регистрация данных и
3) передать результат в клиент
Обратите внимание, что доступ к индексу (который вы подозреваете, чтобы вызвать проблемы) имеет значение только для шага 1. Таким образом, чтобы получить лучшее впечатление, прежде всего, реализовать распределение времени, прошедшего между тремя шагами. Это может быть сделано с помощью SQL * Plus (я использую те же сгенерированные данные, как и в предыдущем ответе)
Доступ к данным
Как мой стол не имеет индекс, выполняя COUNT (*) выполняет ПОЛНЫЙ ТАБЛИЦЫ. Поэтому в худшем случае для получения данных используется дважды в два раза.
SQL> set timi on
SQL> set autotrace on
SQL> select count(*) from mytab;
COUNT(*)
----------
20000
Elapsed: 00:00:01.13
Execution Plan
----------------------------------------------------------
Plan hash value: 3284627250
--------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
--------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5472 (1)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| MYTAB | 20000 | 5472 (1)| 00:00:01 |
--------------------------------------------------------------------
ФСТ готова примерно на одну секунду, поэтому, чтобы получить обе группы приблиз. прошло две секунды.
РЕГИСТРИРУЙТЕСЬ
истекшее время для присоединиться к банку путем моделируется с CTAS джойна запроса.
SQL> create table myRes as
2 select a.SessionOrder rn0, b.SessionOrder rn1
3 from myTab a join myTab b on a.SessionOrder > b.SessionOrder and
4 a.something = 12 and b.something = 14;
Table created.
Elapsed: 00:00:23.65
Регистрация возвращает около 50М строк (из-за больше, чем условие) и занимает около 21 секунд (я вычитаем 2 секунды для доступа к данным).
передает данные Клиента
Мы используем опцию set autotrace traceonly
для подавления вывода запроса на экране клиента, но данные передаются, поэтому мы можем измерять время. (Если вы предоставляете результат на экране, время будет даже намного выше)
SQL> SET ARRAYSIZE 5000
SQL> set autotrace traceonly
SQL> select a.SessionOrder rn0, b.SessionOrder rn1
2 from myTab a join myTab b on a.SessionOrder > b.SessionOrder and
3 a.something = 12 and b.something = 14;
49995000 rows selected.
Elapsed: 00:03:03.89
Execution Plan
----------------------------------------------------------
Plan hash value: 2857240533
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 49M| 667M| 11077 (2)| 00:00:01 |
| 1 | MERGE JOIN | | 49M| 667M| 11077 (2)| 00:00:01 |
| 2 | SORT JOIN | | 10000 | 70000 | 5473 (1)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| MYTAB | 10000 | 70000 | 5472 (1)| 00:00:01 |
|* 4 | SORT JOIN | | 10000 | 70000 | 5473 (1)| 00:00:01 |
|* 5 | TABLE ACCESS FULL| MYTAB | 10000 | 70000 | 5472 (1)| 00:00:01 |
-----------------------------------------------------------------------------
Здесь самое время потратить около 2:40 минут
Резюме
Так в сценарии из общей сложности 3 минуты + только около 2 секунд тратят на доступ к данным (или около 1%). Даже если вы разрезаете доступ к данным до десятой части, вы не увидите практически никакой разницы. Проблема заключается в соединении и даже больше в передаче данных клиенту.
Когда индекс может помочь
И, конечно, это зависит от ...
В особом случае, когда у вас есть очень большой стол с очень маленькими данными с something in (12,14)
вы можете прибыль от индекс, определенный на что-то И SessionOrder. Это позволяет использовать только только доступ к обходному доступу к данным вообще.
Что показывает план выполнения? Сколько строк занимает каждый подзапрос? (Почему вы используете подзапросы, а не просто присоединяетесь к таблицам, и на данный момент это не похоже на синтаксис Oracle). –
Это недопустимый запрос. Алиасы таблиц не определены в области 'ON i_0.rn> i_1.rn' –
Я согласен с Алексом, это определенно не синтаксис Oracle. Тем не менее, это почти декартово соединение. Вы действительно собираетесь присоединяться к каждой строке меньше, чем i_o.rn, к i_o? В качестве примера этот SQL возвращает 4 950 строк: с aset as (выберите rownum r из dba_objects, где rownum <101) выберите a.r, b.r из aset a внутреннее соединение aset b на a.r> b.r. –