powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / чтение плана запроса
25 сообщений из 25, страница 1 из 1
чтение плана запроса
    #39332347
murr31
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Написалазапрос


Код: plsql
1.
2.
3.
4.
5.
6.
7.
 SELECT E.employee_id, 
        E.last_name,
        d.department_name
 FROM employees E, 
      departments D
 WHERE E.department_id = D.department_id 
       AND upper(E.first_name) =  'GUY';



Сделала индекс по функции

CREATE INDEX FIRST_NAME ON EMPLOYEES(UPPER (FIRST_NAME));


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3488509485

---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 43 | 3 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 43 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 1 | 27 | 2 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | FIRST_NAME | 1 | | 1 (0)| 00:00:01 |
|* 5 | INDEX UNIQUE SCAN | DEPT_ID_PK | 1 | | 0 (0)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS | 1 | 16 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

4 - access(UPPER("FIRST_NAME")='GUY')
5 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")

19 rows selected

Пытаюсь прочитать.
1.Операция 4 получает доступ к таблице EMPLOYEES по индексу FIRST_NAME и возвращает ROWID для операции 3
2.Операция 5 получает доступ к таблице DEPARTMENTS по индексу DEPT_ID_PK возвращает ROWID для операции 2
3. Операция 2 выполняет соединения таблиц
4.Операция 1 отдает результат в операцию 0.

...Но как то коряво .... не понимаю, что происходит на 5 операции, помогите разобраться.
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332389
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
План запроса читается снизу вверх.
6. Получаем роувиды таблицы департаментов.
5. Из этого множества построчно обходим (п. 2) и получаем роувиды таблицы департаментов, значение колонки DEPARTMENT_ID которой равно значениям колонки DEPARTMENT_ID таблицы сотрудников
4. Из таблицы сотрудников отбираем по индексу первого имени набор строк
3. Из полученного набора строк сотрудников получаем роувиды
2. Увязываем с построчным проходом департаментов набор из таблицы сотрудников - формируем по завершении каждого обхода набор значений, соответствующих 1 строке департаментов
1. Увязываем все наборы, полученные по каждой строке департамента в одну коллекцию
0. Показываем заданные поля из отобранной коллекции
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332391
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FogelПлан запроса читается снизу вверх.Бред чуть более, чем полностью.
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332403
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicFogelПлан запроса читается снизу вверх.Бред чуть более, чем полностью.
имеющий уши да услышит, не зрячий да прозреет, разум, полный формулировок не видит содержимого.

фраза "Бред чуть более, чем полностью" указывает, что человек соврал на 100 процентов, то есть не прав полностью.
однако тут, Элик, лажа в твоей формулировке, ибо я прав в том, что озвучил ( "План запроса читается снизу вверх" ), а то, что не озвучил , то и не бред, и не правда, а недосказанность - просто нулл в сообщении.
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332412
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fogelибо я правДеточка, это популизм - хотеть казаться правым. Нездоровенький такой.
Fogelв том, что озвучил ( "План запроса читается снизу вверх" ), а то, что не озвучил , то и не бред, и не правда, а недосказанность - просто нулл в сообщении.Да-да. На заборе тоже недосказанно было написано слово "мир" с тремя ошибками.
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332417
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
murr31,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
 SELECT E.employee_id, 
        E.last_name,
        d.department_name
 FROM employees E, 
      departments D
 WHERE E.department_id = D.department_id 
       AND upper(E.first_name) =  'GUY';

---------------------------------------------------------------------------------------------
Plan hash value: 3488509485                                                                  
                                                                                             
---------------------------------------------------------------------------------------------
| Id  | Operation                     | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |             |     1 |    43 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                 |             |       |       |            |          |
|   2 |   NESTED LOOPS                |             |     1 |    43 |     3   (0)| 00:00:01 |
|   3 |    TABLE ACCESS BY INDEX ROWID| EMPLOYEES   |     1 |    27 |     2   (0)| 00:00:01 |
|*  4 |     INDEX RANGE SCAN          | FIRST_NAME  |     1 |       |     1   (0)| 00:00:01 |
|*  5 |    INDEX UNIQUE SCAN          | DEPT_ID_PK  |     1 |       |     0   (0)| 00:00:01 |
|   6 |   TABLE ACCESS BY INDEX ROWID | DEPARTMENTS |     1 |    16 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
                                                                                             
Predicate Information (identified by operation id):                                          
---------------------------------------------------                                          
                                                                                             
   4 - access(UPPER("FIRST_NAME")='GUY')                                                     
   5 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")     


Каждый шаг плана проще всего объяснять как некую процедуру, вложенные шаги которой являются операциями-процедурами, запускаемыми/останавливаемые этой процедурой и постепенно возвращающие в нее свои результаты.

Т.е. в твоем плане это будет так:
0. Запускается SELECT, который запускает NESTED LOOPS из шага 1;
1. NESTED LOOPS шага 1, запускает NESTED LOOPS из шага 2 и по возвращенным строкам(ROWIDs) оттуда выполняет шаг 6, т.е. достает оттуда строки по найденным роуайди из шага 2;
2. NESTED LOOPS шага 2 запускает процедуру из шага 3 (TABLE ACCESS BY INDEX ROWID) и по возвращенным строкам оттуда выполняет шаг 5, т.е. фильтрует эти строки по INDEX UNIQUE SCAN индекса DEPT_ID_PK
3. Шаг 3 - TABLE ACCESS BY INDEX ROWID - запускает шаг 4(INDEX RANGE SCAN) и по возвращенным оттуда ROWID достает строки из EMPLOYEES
4. Шаг 4 сканирует индекс FIRST_NAME через IRS(index range scan) по предикату: access(UPPER("FIRST_NAME")='GUY')
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332418
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
FogelПлан запроса читается снизу вверх.
6. Получаем роувиды таблицы департаментов.
5. Из этого множества построчно обходим (п. 2) и получаем роувиды таблицы департаментов, значение колонки DEPARTMENT_ID которой равно значениям колонки DEPARTMENT_ID таблицы сотрудников
4. Из таблицы сотрудников отбираем по индексу первого имени набор строк
3. Из полученного набора строк сотрудников получаем роувиды
2. Увязываем с построчным проходом департаментов набор из таблицы сотрудников - формируем по завершении каждого обхода набор значений, соответствующих 1 строке департаментов
1. Увязываем все наборы, полученные по каждой строке департамента в одну коллекцию
0. Показываем заданные поля из отобранной коллекцииЕшкин же ж кот, какой бред... ты бы сначала сам планы научился читать...
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332422
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
murr31...
Пытаюсь прочитать.
1.Операция 4 получает доступ к таблице EMPLOYEES по индексу FIRST_NAME и возвращает ROWID для операции 3

+ (правильно), в текущем наборе данных e.rowid

2. выполняется операция 3 (| 3 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES )
, идущая по найденным на первом шаге e.rowid и добавляющая к текущему набору значения полей из E - E.employee_id, E.last_name, результат отдается на шаг |2|
3. выполняется шаг 2 | NESTED LOOPS |, в наличии E.employee_id, E.last_name,
значения E.employee_id из текущей строки набора используются как параметр, отдаваемый на шаг |5|

murr31
2 4.Операция 5 получает доступ к таблице DEPARTMENTS по индексу DEPT_ID_PK возвращает ROWID для операции 2

+ (правильно),
доступ осуществляется по значению E.department_id, полученному в операции |3|,
Этот шаг завершает выполнение шага |2|, по выполнению которого
обеспечивается наличие обеспечивает сохранение E.employee_id, E.last_name, D.ROWID
в текущем выходном наборе, передавая результат на шаг |1|

5. Выполняем шаг | 1 | NESTED LOOPS, используя полученный D.ROWID как параметр, отдаваемый на шаг | 6 | TABLE ACCESS BY INDEX ROWID

6. Выполняем | 6 | TABLE ACCESS BY INDEX ROWID
Завершение этого шага добавляет в выходной набор d.department_name
и завершает шаг |1|

7. Результат отдаем на шаг 0, который выбирает из текущего рабочего набора требуемые
E.employee_id, E.last_name, d.department_name
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332424
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
murr31Пытаюсь прочитатьДля начинающих вот тетенька подробно объясняет Execution Plans - Learn by Example
Имеются некоторые неточности и некоторые банальности разжевываются уж слишком долго, но в целом для базового понимания сойдет (по ссылке есть и видео и pdf).
Fogelя прав в том, что озвучил ( "План запроса читается снизу вверх" )Уже это хреновая формулировка независимо от того, что ты считаешь низом, а что верхом.
План читается от первой листовой операции. Хотя надо сделать оговорку для скаляров в списке выборки.
И то, это справедливо только для serial plans. Для parallel execution все несколько сложнее.
Разбирать дальнейшую чушь нет смысла.
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332425
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
FogelПлан запроса читается снизу вверх.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
SQL> explain plan for select * from dual where 1=0;

Explained.

SQL> @xplan

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------
Plan hash value: 3752461848

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |     2 |     0   (0)|          |
|*  1 |  FILTER            |      |       |       |            |          |
|   2 |   TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter(NULL IS NOT NULL)

14 rows selected.

объяснишь?
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332427
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332428
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopПлан читается от корня, выполнения начинается от первой листовой операцииFixed.
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332453
Фотография SeaGate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopПлан читается от корня, выполнения начинается от первой листовой операции
Немного не понятно, зачем читать от корня, если выполнять от первой листовой операции. Почему не:
Execution plan выполняется от корня, доступ к данным начинается с первой листовой операции (с поправкой на различные scalar subquery, parallel execution etc, т.е. условный "типовой" план в вакууме).
xtenderобъяснишь?
rowsource execution statistics появится после того, как снизу вверх прочитают?
Тогда на эту же тему и пример с конкатенацией (VW_ORE_% - OR-Expansion, 12.2):
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
SQL> var n number
SQL> select /*+ gather_plan_statistics*/
  2         *
  3    from scott.emp
  4   where nvl(:n,empno)=empno;

     EMPNO ENAME      JOB              MGR HIREDATE                   SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ------------------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17.12.1980 00:00:00        800                    20
      7499 ALLEN      SALESMAN        7698 20.02.1981 00:00:00       1600        300         30
      7521 WARD       SALESMAN        7698 22.02.1981 00:00:00       1250        500         30
      7566 JONES      MANAGER         7839 02.04.1981 00:00:00       2975                    20
      7654 MARTIN     SALESMAN        7698 28.09.1981 00:00:00       1250       1400         30
      7698 BLAKE      MANAGER         7839 01.05.1981 00:00:00       2850                    30
      7782 CLARK      MANAGER         7839 09.06.1981 00:00:00       2450                    10
      7839 KING       PRESIDENT            17.11.1981 00:00:00       5000                    10
      7844 TURNER     SALESMAN        7698 08.09.1981 00:00:00       1500          0         30
      7900 JAMES      CLERK           7698 03.12.1981 00:00:00        950                    30
      7902 FORD       ANALYST         7566 03.12.1981 00:00:00       3000                    20
      7934 MILLER     CLERK           7782 23.01.1982 00:00:00       1300                    10
SQL> select * from table(dbms_xplan.display_cursor( format=> 'rowstats last'));

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------
SQL_ID  608graqnaw6jy, child number 0
-------------------------------------
select /*+ gather_plan_statistics*/        *   from scott.emp  where
nvl(:n,empno)=empno

Plan hash value: 1523135839

-------------------------------------------------------------------------------------
| Id  | Operation                      | Name            | Starts | E-Rows | A-Rows |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                 |      1 |        |     12 |
|   1 |  VIEW                          | VW_ORE_DD1C526D |      1 |     13 |     12 |
|   2 |   UNION-ALL                    |                 |      1 |        |     12 |
|*  3 |    FILTER                      |                 |      1 |        |      0 |
|   4 |     TABLE ACCESS BY INDEX ROWID| EMP             |      0 |      1 |      0 |
|*  5 |      INDEX UNIQUE SCAN         | EMP_PK          |      0 |      1 |      0 |
|*  6 |    FILTER                      |                 |      1 |        |     12 |
|   7 |     TABLE ACCESS FULL          | EMP             |      1 |     12 |     12 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(:N IS NOT NULL)
   5 - access("EMPNO"=:N)
   6 - filter(:N IS NULL)



Я смотрел все из вышеприведенных ссылок. У Jonathan Lewis есть каталог тут .
По теме топика рекомендую разбор от Tanel Poder, т.к. там дается системный подход по тому, как проверять, что выполняется, порядок выполнения, а не свод правил (аля, first-child first и т.д.):
http://enkitec.tv/2013/03/13/tanel-poders-hacking-session-how-oracle-sql-plans-are-really-executed-part-1/
http://enkitec.tv/2013/03/14/tanel-poders-hacking-session-how-oracle-sql-plans-are-really-executed-part-2/
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332627
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SeaGaterowsource execution statistics появится после того, как снизу вверх прочитают?не понял я к чему такой вопрос, если в моем примере rowsource execution statistics и так можно сказать просто прочитав план?

SeaGateПо теме топика рекомендую разбор от Tanel Podeэтот конкретно не помню, но у него есть еще пара очень хороших статей:
1. http://blog.tanelpoder.com/2009/04/24/tracing-oracle-sql-plan-execution-with-dtrace/
2. http://blog.tanelpoder.com/2008/06/15/advanced-oracle-troubleshooting-guide-part-6-understanding-oracle-execution-plans-with-os_explain/
и скрипт: http://blog.tanelpoder.com/files/scripts/tools/unix/os_explain
собственно тут Танел и объясняет более конкретно с названиями этих процедур(но сложнее) то, что я говорил тут - 19813880 :
xtenderКаждый шаг плана проще всего объяснять как некую процедуру, вложенные шаги которой являются операциями-процедурами, запускаемыми/останавливаемые этой процедурой и постепенно возвращающие в нее свои результаты
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332654
Фотография SeaGate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderне понял я к чему такой вопрос, если в моем примере rowsource execution statistics и так можно сказать просто прочитав план?
Это было просто предположение того, что будет, если план будет прочитан "снизу вверх" (что я трактую по plan_table.id как 2->1->0).

xtenderи скрипт: http://blog.tanelpoder.com/files/scripts/tools/unix/os_explain
Не вижу, каким прямым образом в задаче определения порядка выполнения операций плана выполнения поможет os_explain.
Для этих целей предназначен http://blog.tanelpoder.com/files/scripts/dtrace/qer_trace.sh , т.к. с os_explain необходимо применять дополнительные телодвижения для получения pstack в нужный момент (во время выполнения запроса).
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332659
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SeaGateЭто было просто предположение того, что будет, если план будет прочитан "снизу вверх" (что я трактую по plan_table.id как 2->1->0).где предположение? Там только странный вопрос...


SeaGateНе вижу, каким прямым образом в задаче определения порядка выполнения операций плана выполнения поможет os_explain.если внимательно посмотришь, то именно в этом скрипте у Танела маппинг реальных процедур к названиям операций плана и в первой ссылке даже показано как именно маппить.
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332663
Фотография SeaGate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,

xtenderесли внимательно посмотришь, то именно в этом скрипте у Танела маппинг реальных процедур к названиям операций плана и в первой ссылке даже показано как именно маппить.
Это я видел. qer_trace.sh позволит получать порядок вызова функций, предварительно запуская скрипт.
Для os_explain сначала нужно получить pstack в момент выполнения.
Если мне нужно гарантированно знать, что и как выполняется, я:
1. создаю сессию
2. запускаю qer_trace.sh
3. выполняю запрос
4. смотри результат

С os_explain ты в какой момент предлагаешь pstack снимать для запроса как у ТС? Задача решаемая, но зачем лишние телодвижения, когда есть qer_trace.sh
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332671
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SeaGateНемного не понятно, зачемВидя ограниченность первой формулировки решил ее поправить, но вторая получилась не лучше.
На этом я решил остановиться, хотя вообще ничего не стоило писать. :)
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332676
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SeaGate,

еще раз... ты первую ссылку таки прочитал? там все и показано:
Код: plsql
1.
2.
dtrace -p 1063 -Fn 'pid$target:oracle:qer*Fetch*:entry pid$target:oracle:qer*Fetch*:return' | tee plan.txt
sed -f os_explain.sed plan.txt
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332859
Фотография SeaGate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,

xtenderеще раз... ты первую ссылку таки прочитал? там все и показано:

dtrace -p 1063 -Fn 'pid$target:oracle:qer*Fetch*:entry pid$target:oracle:qer*Fetch*:return' | tee plan.txt
sed -f os_explain.sed plan.txt

Этого не заметил. Но это сложнее, чем
Код: plsql
1.
qer_trace.sh $spid | os_explain.sed


Мой пост в том, что для определения порядка выполнения rowsource функций проще использовать qer_trace.sh, а не то, что ты предлагаешь, как я тебя понял:
dtrace + строка probes dtrace + tee? + sed? + os_explain.sed (? = опциональные).
Ссылка http://blog.tanelpoder.com/files/scripts/tools/unix/os_explain на bash, sed оттуда получить не сложно (в его tpt_public скриптах я даже не вижу os_explain.sed . os_explain, qer_trace.sh есть), но зачем все эти манипуляции, когда есть qer_trace.sh .
os_explain.sed разве что для "разыменовывания" функций сгодится в конкретной задаче, если в этом есть потребность.
Однако в qer_trace.sh есть то, чего не делает os_explain: трассировка kcbgtcr с указанием файла, блока, функцией доступа из x$kcbwh .
...
Рейтинг: 0 / 0
чтение плана запроса
    #39332928
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SeaGate,

что ж так разжевывать то все надо...
qer_trace для понимания как выполняются строки плана(вопрос ТСа) избыточен, т.к. содержит еще пару лишних инструкций, и не дает связи между строками плана и названиями функций. Между тем dtrace -Fn 'pid$target:oracle:qer*Fetch*:entry pid$target:oracle:qer*Fetch*:return' + маппинг из os_explain(TRANSLATION_STRING) дают именно нужную информацию о порядке выполнения и вложенности.
...
Рейтинг: 0 / 0
чтение плана запроса
    #39333493
Фотография DВА
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как оказывается сложно читать неотформатированные планы ))
...
Рейтинг: 0 / 0
чтение плана запроса
    #39334854
Tyg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Tyg
Гость
xtendermurr31,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
 SELECT E.employee_id, 
        E.last_name,
        d.department_name
 FROM employees E, 
      departments D
 WHERE E.department_id = D.department_id 
       AND upper(E.first_name) =  'GUY';

---------------------------------------------------------------------------------------------
Plan hash value: 3488509485                                                                  
                                                                                             
---------------------------------------------------------------------------------------------
| Id  | Operation                     | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |             |     1 |    43 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS                 |             |       |       |            |          |
|   2 |   NESTED LOOPS                |             |     1 |    43 |     3   (0)| 00:00:01 |
|   3 |    TABLE ACCESS BY INDEX ROWID| EMPLOYEES   |     1 |    27 |     2   (0)| 00:00:01 |
|*  4 |     INDEX RANGE SCAN          | FIRST_NAME  |     1 |       |     1   (0)| 00:00:01 |
|*  5 |    INDEX UNIQUE SCAN          | DEPT_ID_PK  |     1 |       |     0   (0)| 00:00:01 |
|   6 |   TABLE ACCESS BY INDEX ROWID | DEPARTMENTS |     1 |    16 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
                                                                                             
Predicate Information (identified by operation id):                                          
---------------------------------------------------                                          
                                                                                             
   4 - access(UPPER("FIRST_NAME")='GUY')                                                     
   5 - access("E"."DEPARTMENT_ID"="D"."DEPARTMENT_ID")     


Каждый шаг плана проще всего объяснять как некую процедуру, вложенные шаги которой являются операциями-процедурами, запускаемыми/останавливаемые этой процедурой и постепенно возвращающие в нее свои результаты.

Т.е. в твоем плане это будет так:
0. Запускается SELECT, который запускает NESTED LOOPS из шага 1;
1. NESTED LOOPS шага 1, запускает NESTED LOOPS из шага 2 и по возвращенным строкам(ROWIDs) оттуда выполняет шаг 6, т.е. достает оттуда строки по найденным роуайди из шага 2;
2. NESTED LOOPS шага 2 запускает процедуру из шага 3 (TABLE ACCESS BY INDEX ROWID) и по возвращенным строкам оттуда выполняет шаг 5, т.е. фильтрует эти строки по INDEX UNIQUE SCAN индекса DEPT_ID_PK
3. Шаг 3 - TABLE ACCESS BY INDEX ROWID - запускает шаг 4(INDEX RANGE SCAN) и по возвращенным оттуда ROWID достает строки из EMPLOYEES
4. Шаг 4 сканирует индекс FIRST_NAME через IRS(index range scan) по предикату: access(UPPER("FIRST_NAME")='GUY')
Насколько корректно выражение 'фильтрует' в п.2? В предикатах access
...
Рейтинг: 0 / 0
чтение плана запроса
    #39334856
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
TygНасколько корректно выражение 'фильтрует' в п.2? В предикатах accessну, тут дело не в filter/access предикатах вообще, это я просто не вглядывался в сам запрос - реально тут должно быть наличие внешнего ключа и not null, и на самом деле никакого отсева, а просто добавление данных из departments. Кстати, projection по-хорошему надо тоже смотреть/показывать.
...
Рейтинг: 0 / 0
чтение плана запроса
    #39334881
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tyg...
Насколько корректно выражение 'фильтрует' в п.2? В предикатах access
Имхо, смысл в этой фразе применительно конкретно к пункту 2 определенно есть.

Формально соединение по условию в рел алгебре определяется как комбинация (последовательность) декартова произведения с последующей фильтрацией по условию.

Соответственно здесь - строка, приезжающая на шаг 2 с шага 3 будет выброшена из процесса формирования результирующего набора, то есть, по существу, буквально
отфильтрована , если скан индекса на шаге 5 окажется безрезультатным.

Как минимум, мне представляется понятным, о чем речь при таком словоупотреблении.
Хотя конкретный изображенный в плане алгоритм соединения может быть также вполне корректно быть изложен в других термина.

Вот в пункте 1 подозревать отсутствие в таблице строки, rowid которой оказался
найденным в индексе сложнее, и для п1 применение термина 'фильтрует' для конкретного запроса выглядит более искусственным.

Но даже здесь - формально-логически - фильтрует, если исходить из чтения соединения
как комбинации декартова произведения с наложение последующего фильтра
( в этом месте по условию равенства D.rowid для ведущего набора, полученного с шага 2 и ведомого, выбираемого на шаге 6)
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / чтение плана запроса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]