Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Оптимизация запроса / 17 сообщений из 17, страница 1 из 1
05.03.2020, 15:03
    #39934697
DВА
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Имеется такой вот запрос с планом

Код: 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.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
SQL_ID  bnpdmwagby7gv, child number 0			
-------------------------------------			
SELECT SUM(B1.C_UAMOUNT_BASE) VALUE, B1.C_DOC_SRC DOC FROM Z#UDOCUMENT 			
B2, Z#BUPDATING B1, Z#LIMIT A1 WHERE A1.COLLECTION_ID=:B1 AND 			
B1.C_DOC_SRC=B2.ID AND (A1.ID = B1.C_BPLAN_VALUE(+) AND (A1.C_SUBPERIOD 			
IN ( SELECT C1.ID A$1 FROM Z#BM_PERIOD C1 CONNECT BY PRIOR C1.ID = 			
C1.C_UP_PERIOD START WITH C1.ID = :B2 )) AND (A1.C_LIM_ARTICLE IN ( 			
SELECT D1.ID A$1 FROM Z#UB_ARTICLE D1 CONNECT BY PRIOR D1.ID = 			
D1.C_ARCH_UP_LEVEL START WITH D1.ID = :B3 )) AND (A1.C_NAV_CFR IN ( 			
SELECT E1.ID A$1 FROM Z#UB_CFR E1 CONNECT BY PRIOR E1.ID = 			
E1.C_ARCH_UP_LEVEL START WITH E1.ID = :B4 )) AND B2.CLASS_ID = 			
'REQBUDUPD') GROUP BY B1.C_DOC_SRC			
 			
Plan hash value: 3133437956			
 			
---------------------------------------------------------------------------------------------------------------------------------			
| Id  | Operation                                        | Name                         | Rows  | Bytes | Cost (%CPU)| Time     |			
---------------------------------------------------------------------------------------------------------------------------------			
|   0 | SELECT STATEMENT                                 |                              |       |       |    22 (100)|          |			
|   1 |  HASH GROUP BY                                   |                              |     1 |   107 |    22  (19)| 00:00:01 |			
|   2 |   NESTED LOOPS                                   |                              |     1 |   107 |    21  (15)| 00:00:01 |			
|   3 |    NESTED LOOPS                                  |                              |     1 |   107 |    21  (15)| 00:00:01 |			
|   4 |     NESTED LOOPS                                 |                              |     1 |    85 |    20  (15)| 00:00:01 |			
|*  5 |      HASH JOIN                                   |                              |     1 |    64 |    19  (16)| 00:00:01 |			
|   6 |       JOIN FILTER CREATE                         | :BF0000                      |     1 |    56 |    15  (14)| 00:00:01 |			
|*  7 |        HASH JOIN                                 |                              |     1 |    56 |    15  (14)| 00:00:01 |			
|   8 |         NESTED LOOPS                             |                              |     3 |   144 |     9  (12)| 00:00:01 |			
|   9 |          NESTED LOOPS                            |                              |    39 |   144 |     9  (12)| 00:00:01 |			
|  10 |           VIEW                                   | VW_NSO_3                     |     3 |    24 |     6  (17)| 00:00:01 |			
|  11 |            HASH UNIQUE                           |                              |     3 |    78 |     6  (17)| 00:00:01 |			
|* 12 |             CONNECT BY WITH FILTERING (UNIQUE)   |                              |       |       |            |          |			
|  13 |              TABLE ACCESS BY INDEX ROWID         | Z#UB_CFR                     |     1 |    16 |     2   (0)| 00:00:01 |			
|* 14 |               INDEX UNIQUE SCAN                  | PK_Z#UB_CFR_ID               |     1 |       |     1   (0)| 00:00:01 |			
|  15 |              NESTED LOOPS                        |                              |     2 |    58 |     3   (0)| 00:00:01 |			
|  16 |               CONNECT BY PUMP                    |                              |       |       |            |          |			
|  17 |               TABLE ACCESS BY INDEX ROWID BATCHED| Z#UB_CFR                     |     2 |    32 |     1   (0)| 00:00:01 |			
|* 18 |                INDEX RANGE SCAN                  | IDX_Z#UB_CFR_PARENT_COLL     |     2 |       |     0   (0)|          |			
|* 19 |           INDEX RANGE SCAN                       | IDX_Z#LIMIT_COLL             |    13 |       |     0   (0)|          |			
|* 20 |          TABLE ACCESS BY INDEX ROWID             | Z#LIMIT                      |     1 |    40 |     1   (0)| 00:00:01 |			
|  21 |         VIEW                                     | VW_NSO_2                     |     4 |    32 |     6  (17)| 00:00:01 |			
|  22 |          HASH UNIQUE                             |                              |     4 |   104 |     6  (17)| 00:00:01 |			
|* 23 |           CONNECT BY WITH FILTERING (UNIQUE)     |                              |       |       |            |          |			
|  24 |            TABLE ACCESS BY INDEX ROWID           | Z#UB_ARTICLE                 |     1 |    16 |     2   (0)| 00:00:01 |			
|* 25 |             INDEX UNIQUE SCAN                    | PK_Z#UB_ARTICLE_ID           |     1 |       |     1   (0)| 00:00:01 |			
|  26 |            NESTED LOOPS                          |                              |     3 |    87 |     3   (0)| 00:00:01 |			
|  27 |             CONNECT BY PUMP                      |                              |       |       |            |          |			
|  28 |             TABLE ACCESS BY INDEX ROWID BATCHED  | Z#UB_ARTICLE                 |     3 |    48 |     1   (0)| 00:00:01 |			
|* 29 |              INDEX RANGE SCAN                    | IDX_Z#UB_ARTICLE_PARENT_COLL |     3 |       |     0   (0)|          |			
|  30 |       VIEW                                       | VW_NSO_1                     |     4 |    32 |     4  (25)| 00:00:01 |			
|  31 |        HASH UNIQUE                               |                              |     4 |   104 |     4  (25)| 00:00:01 |			
|  32 |         JOIN FILTER USE                          | :BF0000                      |       |       |            |          |			
|* 33 |          CONNECT BY WITH FILTERING (UNIQUE)      |                              |       |       |            |          |			
|  34 |           TABLE ACCESS BY INDEX ROWID            | Z#BM_PERIOD                  |     1 |    16 |     1   (0)| 00:00:01 |			
|* 35 |            INDEX UNIQUE SCAN                     | PK_Z#BM_PERIOD_ID            |     1 |       |     0   (0)|          |			
|  36 |           NESTED LOOPS                           |                              |     3 |    87 |     2   (0)| 00:00:01 |			
|  37 |            CONNECT BY PUMP                       |                              |       |       |            |          |			
|  38 |            TABLE ACCESS BY INDEX ROWID BATCHED   | Z#BM_PERIOD                  |     3 |    48 |     1   (0)| 00:00:01 |			
|* 39 |             INDEX RANGE SCAN                     | Z#IX_Z#BM_PERIOD_REF7        |     3 |       |     0   (0)|          |			
|* 40 |      TABLE ACCESS BY INDEX ROWID BATCHED         | Z#BUPDATING                  |     1 |    21 |     1   (0)| 00:00:01 |			
|* 41 |       INDEX RANGE SCAN                           | Z#IX_Z#BUPDATING_REF5        |     1 |       |     0   (0)|          |			
|* 42 |     INDEX UNIQUE SCAN                            | PK_Z#UDOCUMENT_ID            |     1 |       |     0   (0)|          |			
|* 43 |    TABLE ACCESS BY INDEX ROWID                   | Z#UDOCUMENT                  |     1 |    22 |     1   (0)| 00:00:01 |			
---------------------------------------------------------------------------------------------------------------------------------			
 



При парсинге запроса без переменных генерится вполне устраивающая меня предикатная информация, дающая приличный план доступа

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Predicate Information (identified by operation id):
---------------------------------------------------
 
   5 - access("A1"."C_SUBPERIOD"="A$1")
   7 - access("A1"."C_LIM_ARTICLE"="A$1")
  12 - access("E1"."C_ARCH_UP_LEVEL"=PRIOR "E1"."ID")
  14 - access("E1"."ID"=TO_NUMBER(:B4))
  18 - access("connect$_by$_pump$_017"."PRIOR E1.ID "="E1"."C_ARCH_UP_LEVEL")
  19 - access("A1"."COLLECTION_ID"=TO_NUMBER(:B1))
  20 - filter("A1"."C_NAV_CFR"="A$1")
  23 - access("D1"."C_ARCH_UP_LEVEL"=PRIOR "D1"."ID")
  25 - access("D1"."ID"=TO_NUMBER(:B3))
  29 - access("connect$_by$_pump$_011"."PRIOR D1.ID "="D1"."C_ARCH_UP_LEVEL")
  33 - access("C1"."C_UP_PERIOD"=PRIOR "C1"."ID")
  35 - access("C1"."ID"=TO_NUMBER(:B2))
  39 - access("connect$_by$_pump$_005"."PRIOR C1.ID "="C1"."C_UP_PERIOD")
       filter("C1"."C_UP_PERIOD" IS NOT NULL)
  40 - filter("B1"."C_DOC_SRC" IS NOT NULL)
  41 - access("A1"."ID"="B1"."C_BPLAN_VALUE")
  42 - access("B1"."C_DOC_SRC"="B2"."ID")
  43 - filter("B2"."CLASS_ID"='REQBUDUPD')



При парсинге с приложений в качестве значений биндов периодически прилетают null и предикатная информация в соответствии с ограничением первичного ключа not null выдает идеальный на ее взгляд план с нулевыми чтениями

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
Predicate Information (identified by operation id):
---------------------------------------------------
 
   5 - access("A1"."C_SUBPERIOD"="A$1")
   7 - access("A1"."C_LIM_ARTICLE"="A$1")
 [color=red] 12 - access("E1"."C_ARCH_UP_LEVEL"=PRIOR NULL)
[/color]  14 - access("E1"."ID"=:B4)
  18 - access("connect$_by$_pump$_017"."PRIOR E1.ID "="E1"."C_ARCH_UP_LEVEL")
  19 - access("A1"."COLLECTION_ID"=:B1)
  20 - filter("A1"."C_NAV_CFR"="A$1")
 [color=red] 23 - access("D1"."C_ARCH_UP_LEVEL"=PRIOR NULL)
[/color]  25 - access("D1"."ID"=:B3)
  29 - access("connect$_by$_pump$_011"."PRIOR D1.ID "="D1"."C_ARCH_UP_LEVEL")
[color=red]  33 - access("C1"."C_UP_PERIOD"=PRIOR NULL)
[/color]  35 - access("C1"."ID"=:B2)
  39 - access("connect$_by$_pump$_005"."PRIOR C1.ID "="C1"."C_UP_PERIOD")
       filter("C1"."C_UP_PERIOD" IS NOT NULL)
  40 - filter("B1"."C_DOC_SRC" IS NOT NULL)
  41 - access("A1"."ID"="B1"."C_BPLAN_VALUE")
  42 - access("B1"."C_DOC_SRC"="B2"."ID")
  43 - filter("B2"."CLASS_ID"='REQBUDUPD')



Следом прилетают не нулевые значения и начинаются танцы с бубном адапривных курсоров с механизмом Extended Cursor Sharing
Курсоры скачут аки кони, планы большей частью не удачные, поскольку сам запрос вызывается не часто.

Вопрос, как бы закрепить план с хорошей предикатной информацией
12 - access("E1"."C_ARCH_UP_LEVEL"=PRIOR "E1"."ID")

вместо
12 - access("E1"."C_ARCH_UP_LEVEL"=PRIOR NULL)
...
Рейтинг: 0 / 0
05.03.2020, 15:32
    #39934729
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
DВА,

Так и закрепи патчем/профилем/бейслайном...
...
Рейтинг: 0 / 0
05.03.2020, 15:49
    #39934741
DВА
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
xtender
DВА,

Так и закрепи патчем/профилем/бейслайном...


так вот и не могу сообразить как
планы-то одинаковые
...
Рейтинг: 0 / 0
05.03.2020, 16:18
    #39934770
feagor
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
DВА,
хэши то должны отличаться по идее?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
/*ACHTUNG! План будет применен на второе выполнение запроса! 1 Будет со старым планом*/
-- загрузка плана настроенного запроса
declare
  l_sql_id_src varchar2(13)    :='bnpdmwagby7gv';   -- sql_id образца
  l_plan_hash_value_src number := 3133437956;       -- plan_hash_value образца
  l_sql_id_trg  varchar2(13)   :='bnpdmwagby7gv';   -- sql_id настраиваемого запроса
  l_sql_text_trg clob;  
  l_res number;  
begin
  -- текст запроса для настройки
  select a.sql_fulltext into l_sql_text_trg
    from v$sqlarea a 
   where a.sql_id = l_sql_id_trg
   and   rownum<2;
  -- загрузка плана и создание SQL plan baseline
  l_res := dbms_spm.load_plans_from_cursor_cache( 
              sql_id => l_sql_id_src, 
              plan_hash_value => l_plan_hash_value_src, 
              sql_text => l_sql_text_trg);
  dbms_output.put_line(l_res);  
end; 
...
Рейтинг: 0 / 0
05.03.2020, 16:28
    #39934775
DВА
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
feagor,

единственное чем планы отличаются, это Predicate Information
...
Рейтинг: 0 / 0
05.03.2020, 16:29
    #39934777
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
DВА,

трудно тебя понять... выгрузи по обоим планам/запросам отчет sqldb360: https://github.com/sqldb360/sqldb360

можешь на почту мне кинуть, если светить не хочешь
...
Рейтинг: 0 / 0
05.03.2020, 16:49
    #39934790
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
feagor,

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

DВА,

alter session и отключить либо bind peeking либо одну из трансормаций не варинат?
...
Рейтинг: 0 / 0
05.03.2020, 16:53
    #39934794
Кобанчег
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Кобанчег
alter session
Хотя хинт же вроде можно и патчем прилепить, но
Код: plaintext
opt_param('_optim_peek_user_binds' 'false')
не работал, по крайней мере на прошлых версиях.
...
Рейтинг: 0 / 0
05.03.2020, 17:22
    #39934825
DВА
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Кобанчег
Кобанчег
alter session
Хотя хинт же вроде можно и патчем прилепить, но
Код: plaintext
opt_param('_optim_peek_user_binds' 'false')
не работал, по крайней мере на прошлых версиях.


хинт работает, но красивый курсор быстро инвалидится, когда в него прилетают null значения, генерится не красивый, и дальше все выполняются по нему )
...
Рейтинг: 0 / 0
05.03.2020, 17:36
    #39934835
Alexander Anokhin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Это может быть неверная гипотеза, что эти планы отличаются по производительности для одних и тех же вводных.
Есть ли SQL monitor report'ы доказывающие обратное?

test case
Код: 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.
drop table t1;
create table t1 as select rownum id, rownum + 1 parent_id from dual connect by level <= 1000000;
create index i1 on t1(parent_id);
create index i2 on t1(id);

 select count(*) 
   from t1
connect by prior id = parent_id
  start with id = 10;

select * from table(dbms_xplan.display_cursor(null, null, 'basic predicate'));

-------------------------------------------------------
| Id  | Operation                              | Name |
-------------------------------------------------------
|   0 | SELECT STATEMENT                       |      |
|   1 |  SORT AGGREGATE                        |      |
|*  2 |   CONNECT BY WITH FILTERING            |      |
|   3 |    TABLE ACCESS BY INDEX ROWID BATCHED | T1   |
|*  4 |     INDEX RANGE SCAN                   | I2   |
|   5 |    NESTED LOOPS                        |      |
|   6 |     CONNECT BY PUMP                    |      |
|   7 |     TABLE ACCESS BY INDEX ROWID BATCHED| T1   |
|*  8 |      INDEX RANGE SCAN                  | I1   |
-------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("PARENT_ID"=PRIOR NULL)
   4 - access("ID"=10)
   8 - access("connect$_by$_pump$_002"."prior id "="PARENT_ID")



Похоже просто reporting issue.
...
Рейтинг: 0 / 0
05.03.2020, 18:01
    #39934851
Alexander Anokhin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
тоже самое через explain plan
Код: 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.
SQL> explain plan for
  2   select count(*)
  3     from t1
  4  connect by prior id = parent_id
  5    start with id = 10;
Explained

SQL> select * from table(dbms_xplan.display(null,null,'basic predicate'));

-----------------------------------------------
| Id  | Operation                      | Name |
-----------------------------------------------
|   0 | SELECT STATEMENT               |      |
|   1 |  SORT AGGREGATE                |      |
|*  2 |   CONNECT BY WITH FILTERING    |      |
|   3 |    TABLE ACCESS BY INDEX ROWID | T1   |
|*  4 |     INDEX UNIQUE SCAN          | I2   |
|   5 |    NESTED LOOPS                |      |
|   6 |     CONNECT BY PUMP            |      |
|   7 |     TABLE ACCESS BY INDEX ROWID| T1   |
|*  8 |      INDEX UNIQUE SCAN         | I1   |
-----------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("PARENT_ID"=PRIOR "ID")
   4 - access("ID"=10)
   8 - access("connect$_by$_pump$_002"."prior id "="PARENT_ID")
...
Рейтинг: 0 / 0
05.03.2020, 18:22
    #39934863
Alexander Anokhin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
перед explain plan индексы были переделаны в unique, поэтому unique scan, это можно игнорировать.
...
Рейтинг: 0 / 0
05.03.2020, 19:41
    #39934903
Alexander Anokhin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Alexander Anokhin

Похоже просто reporting issue.


Вот тут описано Different Information Provided by v$sql_plan and explain plan (Doc ID 734133.1) , хотя объяснение довольно таки странное, что, вероятно, объясняется тем, что оно было дано аж в 2007 году для версии 10.2.0.3 ( https://support.oracle.com/epmos/faces/BugDisplay?id=6447953 ).

Можно пойти дальше
Код: 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.
alter session set "_connect_by_use_union_all"="old_plan_mode";

 select count(*) 
   from t1
connect by prior id = parent_id
  start with id = 10;

select * from table(dbms_xplan.display_cursor(null, null, 'basic predicate'));

-----------------------------------------------
| Id  | Operation                      | Name |
-----------------------------------------------
|   0 | SELECT STATEMENT               |      |
|   1 |  SORT AGGREGATE                |      |
|*  2 |   CONNECT BY WITH FILTERING    |      |
|   3 |    TABLE ACCESS BY INDEX ROWID | T1   |
|*  4 |     INDEX UNIQUE SCAN          | I2   |
|   5 |    NESTED LOOPS                |      |
|   6 |     CONNECT BY PUMP            |      |
|   7 |     TABLE ACCESS BY INDEX ROWID| T1   |
|*  8 |      INDEX UNIQUE SCAN         | I1   |
-----------------------------------------------

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

   2 - access("PARENT_ID"=PRIOR NULL)
   4 - access("ID"=10)
   8 - access("PARENT_ID"=PRIOR NULL)
...
Рейтинг: 0 / 0
06.03.2020, 17:35
    #39935277
DВА
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Alexander Anokhin
Это может быть неверная гипотеза, что эти планы отличаются по производительности для одних и тех же вводных.

Да, возможно я не в том вижу причину, тогда тем более не понятно, что при выполнении из приложения и sqlplus с теми же самыми значениями биндов и потому же самому плану, более того, с тем же самым sql_id, но новым курсором, количество логических чтений отличается на порядок.
...
Рейтинг: 0 / 0
06.03.2020, 18:15
    #39935284
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
DВА,

Недостаточно информации, чтобы делать какие-либо выводы.
...
Рейтинг: 0 / 0
08.03.2020, 23:54
    #39935612
Melkomyagkii_newbi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
DВА
Кобанчег
пропущено...
Хотя хинт же вроде можно и патчем прилепить, но
Код: plaintext
opt_param('_optim_peek_user_binds' 'false')
не работал, по крайней мере на прошлых версиях.


хинт работает, но красивый курсор быстро инвалидится, когда в него прилетают null значения, генерится не красивый, и дальше все выполняются по нему )


а какая причина инвалидации в gv$sql_shared_cursor? По идее как раз же не должен подглядывать что там прилетает.
...
Рейтинг: 0 / 0
10.03.2020, 02:38
    #39935778
х.з.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
DВА
не понятно, что при выполнении из приложения и sqlplus с теми же самыми значениями биндов и потому же самому плану, более того, с тем же самым sql_id, но новым курсором, количество логических чтений отличается на порядок.


может поможет: https://hourim.wordpress.com/?s=phv2
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Оптимизация запроса / 17 сообщений из 17, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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