Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / чтение плана запроса / 25 сообщений из 25, страница 1 из 1
23.10.2016, 18:09
    #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
23.10.2016, 21:52
    #39332389
Fogel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
План запроса читается снизу вверх.
6. Получаем роувиды таблицы департаментов.
5. Из этого множества построчно обходим (п. 2) и получаем роувиды таблицы департаментов, значение колонки DEPARTMENT_ID которой равно значениям колонки DEPARTMENT_ID таблицы сотрудников
4. Из таблицы сотрудников отбираем по индексу первого имени набор строк
3. Из полученного набора строк сотрудников получаем роувиды
2. Увязываем с построчным проходом департаментов набор из таблицы сотрудников - формируем по завершении каждого обхода набор значений, соответствующих 1 строке департаментов
1. Увязываем все наборы, полученные по каждой строке департамента в одну коллекцию
0. Показываем заданные поля из отобранной коллекции
...
Рейтинг: 0 / 0
23.10.2016, 22:05
    #39332391
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
FogelПлан запроса читается снизу вверх.Бред чуть более, чем полностью.
...
Рейтинг: 0 / 0
23.10.2016, 22:42
    #39332403
Fogel
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
ElicFogelПлан запроса читается снизу вверх.Бред чуть более, чем полностью.
имеющий уши да услышит, не зрячий да прозреет, разум, полный формулировок не видит содержимого.

фраза "Бред чуть более, чем полностью" указывает, что человек соврал на 100 процентов, то есть не прав полностью.
однако тут, Элик, лажа в твоей формулировке, ибо я прав в том, что озвучил ( "План запроса читается снизу вверх" ), а то, что не озвучил , то и не бред, и не правда, а недосказанность - просто нулл в сообщении.
...
Рейтинг: 0 / 0
23.10.2016, 23:07
    #39332412
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
Fogelибо я правДеточка, это популизм - хотеть казаться правым. Нездоровенький такой.
Fogelв том, что озвучил ( "План запроса читается снизу вверх" ), а то, что не озвучил , то и не бред, и не правда, а недосказанность - просто нулл в сообщении.Да-да. На заборе тоже недосказанно было написано слово "мир" с тремя ошибками.
...
Рейтинг: 0 / 0
23.10.2016, 23:18
    #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
23.10.2016, 23:20
    #39332418
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
FogelПлан запроса читается снизу вверх.
6. Получаем роувиды таблицы департаментов.
5. Из этого множества построчно обходим (п. 2) и получаем роувиды таблицы департаментов, значение колонки DEPARTMENT_ID которой равно значениям колонки DEPARTMENT_ID таблицы сотрудников
4. Из таблицы сотрудников отбираем по индексу первого имени набор строк
3. Из полученного набора строк сотрудников получаем роувиды
2. Увязываем с построчным проходом департаментов набор из таблицы сотрудников - формируем по завершении каждого обхода набор значений, соответствующих 1 строке департаментов
1. Увязываем все наборы, полученные по каждой строке департамента в одну коллекцию
0. Показываем заданные поля из отобранной коллекцииЕшкин же ж кот, какой бред... ты бы сначала сам планы научился читать...
...
Рейтинг: 0 / 0
23.10.2016, 23:26
    #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
23.10.2016, 23:33
    #39332424
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
murr31Пытаюсь прочитатьДля начинающих вот тетенька подробно объясняет Execution Plans - Learn by Example
Имеются некоторые неточности и некоторые банальности разжевываются уж слишком долго, но в целом для базового понимания сойдет (по ссылке есть и видео и pdf).
Fogelя прав в том, что озвучил ( "План запроса читается снизу вверх" )Уже это хреновая формулировка независимо от того, что ты считаешь низом, а что верхом.
План читается от первой листовой операции. Хотя надо сделать оговорку для скаляров в списке выборки.
И то, это справедливо только для serial plans. Для parallel execution все несколько сложнее.
Разбирать дальнейшую чушь нет смысла.
...
Рейтинг: 0 / 0
23.10.2016, 23:34
    #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
23.10.2016, 23:45
    #39332427
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
...
Рейтинг: 0 / 0
23.10.2016, 23:52
    #39332428
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
dbms_photoshopПлан читается от корня, выполнения начинается от первой листовой операцииFixed.
...
Рейтинг: 0 / 0
24.10.2016, 06:54
    #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
24.10.2016, 11:59
    #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
24.10.2016, 12:34
    #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
24.10.2016, 12:42
    #39332659
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
SeaGateЭто было просто предположение того, что будет, если план будет прочитан "снизу вверх" (что я трактую по plan_table.id как 2->1->0).где предположение? Там только странный вопрос...


SeaGateНе вижу, каким прямым образом в задаче определения порядка выполнения операций плана выполнения поможет os_explain.если внимательно посмотришь, то именно в этом скрипте у Танела маппинг реальных процедур к названиям операций плана и в первой ссылке даже показано как именно маппить.
...
Рейтинг: 0 / 0
24.10.2016, 12:46
    #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
24.10.2016, 12:50
    #39332671
dbms_photoshop
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
SeaGateНемного не понятно, зачемВидя ограниченность первой формулировки решил ее поправить, но вторая получилась не лучше.
На этом я решил остановиться, хотя вообще ничего не стоило писать. :)
...
Рейтинг: 0 / 0
24.10.2016, 12:55
    #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
24.10.2016, 15:26
    #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
24.10.2016, 16:12
    #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
25.10.2016, 12:38
    #39333493
DВА
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
как оказывается сложно читать неотформатированные планы ))
...
Рейтинг: 0 / 0
26.10.2016, 23:04
    #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
26.10.2016, 23:11
    #39334856
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
TygНасколько корректно выражение 'фильтрует' в п.2? В предикатах accessну, тут дело не в filter/access предикатах вообще, это я просто не вглядывался в сам запрос - реально тут должно быть наличие внешнего ключа и not null, и на самом деле никакого отсева, а просто добавление данных из departments. Кстати, projection по-хорошему надо тоже смотреть/показывать.
...
Рейтинг: 0 / 0
27.10.2016, 00:21
    #39334881
booby
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
чтение плана запроса
Tyg...
Насколько корректно выражение 'фильтрует' в п.2? В предикатах access
Имхо, смысл в этой фразе применительно конкретно к пункту 2 определенно есть.

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

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

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

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

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


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