Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Два плана. Как сказать по-умному, чем они отличаются?  [new]
trak
Member

Откуда: spb.ru
Сообщений: 802
Вот два плана, первый, неправильный по мнению CBO, но работает быстрее и меньше логических чтений:
---------------------------------------------------------------------------------------------------------
| Id  | Operation                           |  Name                        | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                              |  4956 |   788K|   643   (3)|
|*  1 |  HASH JOIN SEMI                     |                              |  4956 |   788K|   643   (3)|
|   2 |   TABLE ACCESS BY INDEX ROWID       | M200_RELIEF                  |  8252 |  1095K|   633   (3)|
|*  3 |    DOMAIN INDEX                     | M200_RELIEF_G_IDX            |       |       |            |
|   4 |   VIEW                              | VW_NSO_1                     |   218 |  5886 |            |
|   5 |    NESTED LOOPS                     |                              |   218 | 25506 |    10  (10)|
|   6 |     VIEW                            | GP_LPU_VIEW                  |     2 |    68 |            |
|   7 |      UNION-ALL                      |                              |       |       |            |
|*  8 |       FILTER                        |                              |       |       |            |
|   9 |        NESTED LOOPS                 |                              |     1 |   121 |     4  (25)|
|  10 |         NESTED LOOPS                |                              |     2 |    38 |     3  (34)|
|  11 |          TABLE ACCESS BY INDEX ROWID| B_USER                       |     1 |    11 |     2  (50)|
|* 12 |           INDEX UNIQUE SCAN         | B_USER_NAME_IDX              |     1 |       |            |
|* 13 |          INDEX RANGE SCAN           | B_USER_TO_GP_LPU_PK_IDX      |     2 |    16 |     2  (50)|
|  14 |         TABLE ACCESS BY INDEX ROWID | GP_LPU                       |     1 |   102 |     2  (50)|
|* 15 |          INDEX UNIQUE SCAN          | GP_LPU_PK                    |     1 |       |            |
|  16 |        SORT AGGREGATE               |                              |     1 |       |            |
|  17 |         TABLE ACCESS FULL           | B_LPU_MASK                   |     1 |       |     3  (34)|
|  18 |       NESTED LOOPS                  |                              |     1 |   134 |     6  (17)|
|  19 |        NESTED LOOPS                 |                              |     1 |    32 |     5  (20)|
|  20 |         NESTED LOOPS                |                              |     1 |    24 |     4  (25)|
|  21 |          TABLE ACCESS BY INDEX ROWID| B_USER                       |     1 |    11 |     2  (50)|
|* 22 |           INDEX UNIQUE SCAN         | B_USER_NAME_IDX              |     1 |       |            |
|  23 |          TABLE ACCESS FULL          | B_LPU_MASK                   |     1 |    13 |     3  (34)|
|* 24 |         INDEX RANGE SCAN            | B_USER_TO_GP_LPU_PK_IDX      |     1 |     8 |            |
|  25 |        TABLE ACCESS BY INDEX ROWID  | GP_LPU                       |     1 |   102 |     2  (50)|
|* 26 |         INDEX UNIQUE SCAN           | GP_LPU_PK                    |     1 |       |            |
|  27 |     TABLE ACCESS BY INDEX ROWID     | M200_NOMENCLATURE_REF        |   109 |  9047 |    10  (10)|
|* 28 |      DOMAIN INDEX                   | M200_NOMENCLATURE_REF_G_IDX  |       |       |            |
---------------------------------------------------------------------------------------------------------

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

   1 - access("M"."NOMENCLATURE"="VW_NSO_1"."NOMENCLATURE")
   3 - access((M."GEOLOC","MDSYS"."SDO_GEOMETRY"(2003,NULL,NULL,"MDSYS"."SDO_ELEM_INFO_ARRAY"(1,3,3),"MDS
              YS"."SDO_ORDINATE_ARRAY"(33.54057300,55.84240600,33.57358800,55.85907200)),'querytype=WINDOW')='TRUE')
   8 - filter( (SELECT /*+ */ COUNT(*) FROM "GIS"."B_LPU_MASK" "G")=0)
  12 - access("B"."NAME"=USER@!)
  13 - access("B"."USER_ID"="C"."USER_ID")
  15 - access("A"."LPU_ID"="C"."LPU_ID")
  22 - access("B"."NAME"=USER@!)
  24 - access("B"."USER_ID"="C"."USER_ID" AND "C"."LPU_ID"="D"."LPU_ID")
  26 - access("A"."LPU_ID"="C"."LPU_ID")
  28 - access((N."GEOLOC","T"."GEOLOC",'querytype=window')='TRUE')


Вот второй, CBO выбирает его, но он работает сильно медленее (раз в 10):
------------------------------------------------------------------------------------------------------------
| Id  | Operation                             |  Name                         | Rows  | Bytes | Cost (%CPU)|
------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |                               |  4956 |   788K|   449   (7)|
|   1 |  TABLE ACCESS BY INDEX ROWID          | M200_RELIEF                   |    23 |  3128 |   449   (7)|
|   2 |   NESTED LOOPS                        |                               |  4956 |   788K|   449   (7)|
|   3 |    VIEW                               | VW_NSO_1                      |   218 |  5886 |            |
|   4 |     SORT UNIQUE                       |                               |   218 | 25506 |            |
|   5 |      NESTED LOOPS                     |                               |   218 | 25506 |    10  (10)|
|   6 |       VIEW                            | GP_LPU_VIEW                   |     2 |    68 |            |
|   7 |        UNION-ALL                      |                               |       |       |            |
|*  8 |         FILTER                        |                               |       |       |            |
|   9 |          NESTED LOOPS                 |                               |     1 |   121 |     4  (25)|
|  10 |           NESTED LOOPS                |                               |     2 |    38 |     3  (34)|
|  11 |            TABLE ACCESS BY INDEX ROWID| B_USER                        |     1 |    11 |     2  (50)|
|* 12 |             INDEX UNIQUE SCAN         | B_USER_NAME_IDX               |     1 |       |            |
|* 13 |            INDEX RANGE SCAN           | B_USER_TO_GP_LPU_PK_IDX       |     2 |    16 |     2  (50)|
|  14 |           TABLE ACCESS BY INDEX ROWID | GP_LPU                        |     1 |   102 |     2  (50)|
|* 15 |            INDEX UNIQUE SCAN          | GP_LPU_PK                     |     1 |       |            |
|  16 |          SORT AGGREGATE               |                               |     1 |       |            |
|  17 |           TABLE ACCESS FULL           | B_LPU_MASK                    |     1 |       |     3  (34)|
|  18 |         NESTED LOOPS                  |                               |     1 |   134 |     6  (17)|
|  19 |          NESTED LOOPS                 |                               |     1 |    32 |     5  (20)|
|  20 |           NESTED LOOPS                |                               |     1 |    24 |     4  (25)|
|  21 |            TABLE ACCESS BY INDEX ROWID| B_USER                        |     1 |    11 |     2  (50)|
|* 22 |             INDEX UNIQUE SCAN         | B_USER_NAME_IDX               |     1 |       |            |
|  23 |            TABLE ACCESS FULL          | B_LPU_MASK                    |     1 |    13 |     3  (34)|
|* 24 |           INDEX RANGE SCAN            | B_USER_TO_GP_LPU_PK_IDX       |     1 |     8 |            |
|  25 |          TABLE ACCESS BY INDEX ROWID  | GP_LPU                        |     1 |   102 |     2  (50)|
|* 26 |           INDEX UNIQUE SCAN           | GP_LPU_PK                     |     1 |       |            |
|  27 |       TABLE ACCESS BY INDEX ROWID     | M200_NOMENCLATURE_REF         |   109 |  9047 |    10  (10)|
|* 28 |        DOMAIN INDEX                   | M200_NOMENCLATURE_REF_G_IDX   |       |       |            |
|  29 |    BITMAP CONVERSION TO ROWIDS        |                               |       |       |            |
|  30 |     BITMAP AND                        |                               |       |       |            |
|  31 |      BITMAP CONVERSION FROM ROWIDS    |                               |       |       |            |
|  32 |       SORT ORDER BY                   |                               |       |       |            |
|  33 |        DOMAIN INDEX                   | M200_RELIEF_G_IDX             |  2273 |       |            |
|  34 |      BITMAP CONVERSION FROM ROWIDS    |                               |       |       |            |
|* 35 |       INDEX RANGE SCAN                | M200_RELIEF_NOMENCLATURE_IDX  |  2273 |       |            |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------

   8 - filter( (SELECT /*+ */ COUNT(*) FROM "GIS"."B_LPU_MASK" "G")=0)
  12 - access("B"."NAME"=USER@!)
  13 - access("B"."USER_ID"="C"."USER_ID")
  15 - access("A"."LPU_ID"="C"."LPU_ID")
  22 - access("B"."NAME"=USER@!)
  24 - access("B"."USER_ID"="C"."USER_ID" AND "C"."LPU_ID"="D"."LPU_ID")
  26 - access("A"."LPU_ID"="C"."LPU_ID")
  28 - access((N."GEOLOC","T"."GEOLOC",'querytype=window')='TRUE')
  35 - access("M"."NOMENCLATURE"="VW_NSO_1"."NOMENCLATURE")


То есть вопрос даже не в том, почему лажается CBO.
Вопрос в том, как сказать, чем они отличаются в корне, кроме того, что в выбраном CBO плане используется индекс M200_RELIEF_NOMENCLATURE_IDX?
Я временами кака собака, понимаю, а сказат не могу :) (Это мне для самообразования :)
28 ноя 06, 08:58    [3459101]     Ответить | Цитировать Сообщить модератору
 Re: Два плана. Как сказать по-умному, чем они отличаются?  [new]
Бабичев Сергей
Member

Откуда:
Сообщений: 2498
Наиболее сильно в глаза бросается то, что во втором плане используются BITMAP CONVERSION, а в первом их нет.
Как вариант - запретить оптимизатору использовать такого рода преобразования и посмотреть, какой план он построит в этом случае и как запрос будет выполняться с таким планом...
28 ноя 06, 09:23    [3459193]     Ответить | Цитировать Сообщить модератору
 Re: Два плана. Как сказать по-умному, чем они отличаются?  [new]
trak
Member

Откуда: spb.ru
Сообщений: 802
Бабичев Сергей
Наиболее сильно в глаза бросается то, что во втором плане используются BITMAP CONVERSION, а в первом их нет.
Как вариант - запретить оптимизатору использовать такого рода преобразования и посмотреть, какой план он построит в этом случае и как запрос будет выполняться с таким планом...

Самое забавное, в этой ситауции, что в том случае, если в схеме меньше данных, и селективность этого "не_нужного" индекса хуже, то он и не используется.
P.S. Спасибо!
28 ноя 06, 09:33    [3459227]     Ответить | Цитировать Сообщить модератору
 Re: Два плана. Как сказать по-умному, чем они отличаются?  [new]
Alexander Dubrovsky
Member [заблокирован]

Откуда:
Сообщений: 4624
А если ставить хинт FIRST_ROWS или ALL_ROWS план один и тот-же?
Быстрее исполняется или требует меньше ресурсов - разные ведь вещи.
28 ноя 06, 09:56    [3459343]     Ответить | Цитировать Сообщить модератору
 Re: Два плана. Как сказать по-умному, чем они отличаются?  [new]
trak
Member

Откуда: spb.ru
Сообщений: 802
Alexander Dubrovsky
А если ставить хинт FIRST_ROWS или ALL_ROWS план один и тот-же?
Быстрее исполняется или требует меньше ресурсов - разные ведь вещи.

Вообще никак не меняется.
Зато есть забавные строчки в трейсе CBO:
SINGLE TABLE ACCESS PATH
  No statistics type defined for function SDO_3GL
  No default cost defined for function SDO_3GL
  No statistics type defined for function SDO_3GL
  No default selectivity defined for function SDO_3GL
  TABLE: M200_RELIEF     ORIG CDN: 825212  ROUNDED CDN: 8252  CMPTD CDN: 8252
  Access path: tsc  Resc:  9915  Resp:  1139
  ****** trying bitmap/domain indexes ******
  No statistics type defined for index M200_RELIEF_G_IDX
  No statistics type defined for indextype of index M200_RELIEF_G_IDX
  No default costs defined for indextype of index M200_RELIEF_G_IDX
Column:     GEOLOC  Col#: 6      Table: M200_RELIEF   Alias:  M
    NO STATISTICS  (using defaults)
    NDV: 25788     NULLS: 0         DENS: 3.8778e-05
    NO HISTOGRAM: #BKT: 0 #VAL: 0
  Access path: index (index-only)
      Index: M200_RELIEF_G_IDX
  TABLE: M200_RELIEF
      USER_CPU: 38500  USER_IO: 3 
  Access path: index (domain index)
      Index: M200_RELIEF_G_IDX
  TABLE: M200_RELIEF
      USER_CPU: none  USER_IO: none
  No statistics type defined for function SDO_3GL
  No default cost defined for function SDO_3GL
******** Domain index access path accepted ********
Cost: 633 Cost_io: 616 Cost_cpu: 56059009.153626 Selectivity: 0.010000
Not believed to be index-only.

Ну что не будет статистики на поле типа spatial — это можно понять, но вот как он высчитал
NDV (количество различных значений на него), вообще загадка.
28 ноя 06, 10:20    [3459483]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить