Страницы

Поиск по вопросам

воскресенье, 22 декабря 2019 г.

Медленно выполняется запрос Oracle

#sql #oracle


Есть запрос:

SELECT zxp.rulon.ukey,
       n, nz, bz, zxp.rulon.ms, tz, ts,
       round(hz,2) HZ, hdm, hdp, zxp.rulon.h1,
       l, round(pf,2) PF, pt, pu, pdm, pdp,
       pbm, pbp, pe, zxp.mc.ukey, naim, 
       LDM, LDP, LBM, LBP, H0, tr, tv, DOP,
       zxp.graph.irez as Broken, 
       K_Z as Brigade
FROM   zxp.rulon, zxp.mc, zxp.graph
WHERE  ts BETWEEN to_date('02.01.2016 7:00:00',  'dd.mm.yyyy hh24:mi:ss')
       AND to_date('02.01.2016 15:00:00', 'dd.mm.yyyy hh24:mi:ss')
AND    zxp.rulon.ms   = zxp.mc.ukey     
AND    zxp.rulon.ukey = zxp.graph.u_rul  
AND    k = (
         SELECT min(k)
         FROM   zxp.Graph
         WHERE  zxp.rulon.ukey = zxp.graph.u_rul
       )
ORDER  BY  ts


Но его выполнение занимает от 4 секунд и выше. Можно ли его оптимизировать?

zxp.Rulon:

UKEY    NUMBER
N   NUMBER
ADR NUMBER
NZ  NUMBER
MS  NUMBER
TR  DATE
TZ  DATE
TV  DATE
TS  DATE
TM  NUMBER
SK  NUMBER
DOP NUMBER
BZ  NUMBER
HZ  NUMBER
HZZ NUMBER
HDM NUMBER
HDP NUMBER
H0  NUMBER
H1  NUMBER
L   NUMBER
LDM NUMBER
LDP NUMBER
LBM NUMBER
LBP NUMBER
PF  NUMBER
PT  NUMBER
PDM NUMBER
PDP NUMBER
PBM NUMBER
PBP NUMBER
PU  NUMBER
PE  NUMBER
L_1 NUMBER
L_2 NUMBER
L_3 NUMBER
L_4 NUMBER
H1S NUMBER
H2S NUMBER
H3S NUMBER
H4SI    NUMBER
H1SI    NUMBER
T1S NUMBER
T2S NUMBER
T3S NUMBER
T4S NUMBER
D1  NUMBER
D2  NUMBER
D3  NUMBER
D4  NUMBER
GH4N    NUMBER
GH4Z    NUMBER
GH4S    NUMBER
GH1Z    NUMBER
GH1S    NUMBER
L4  NUMBER
D_RR    NUMBER
D_RV    NUMBER
K_T NUMBER
K_Z NUMBER
F_REZ1  NUMBER
F_REZ2  NUMBER
F_REZ3  NUMBER
F_REZ4  NUMBER
I_REZ1  NUMBER
I_REZ2  NUMBER
I_REZ3  NUMBER
I_REZ4  NUMBER


Graph:

T2  NUMBER
T3  NUMBER
T4  NUMBER
DL  NUMBER
IREZ    NUMBER
FREZ    NUMBER
LOGBITS NUMBER
UKEY    NUMBER
U_RUL   NUMBER
K   NUMBER
T   DATE
H4  NUMBER
H1  NUMBER
V1  NUMBER
V2  NUMBER
V3  NUMBER
V4  NUMBER


Это то что вы просили ? структура таблицы ? 

Plan hash value: 515981838

--------------------------------------------------------------------------------------------------------
| Id  | Operation                          | Name      | Rows  | Bytes |TempSpc|
Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                   |           |  1653 |   663K|       |
  332   (2)| 00:00:04 |
|   1 |  SORT ORDER BY                     |           |  1653 |   663K|  1672K|
  332   (2)| 00:00:04 |
|*  2 |   VIEW                             | VW_WIF_1  |  1653 |   663K|       |
  184   (2)| 00:00:03 |
|   3 |    WINDOW SORT                     |           |  1653 |   384K|   872K|
  184   (2)| 00:00:03 |
|*  4 |     FILTER                         |           |       |       |       |
           |          |
|   5 |      TABLE ACCESS BY INDEX ROWID   | GRAPH     |  3320 |   110K|       |
   88   (2)| 00:00:02 |
|   6 |       NESTED LOOPS                 |           |  1653 |   384K|       |
   94   (2)| 00:00:02 |
|*  7 |        HASH JOIN                   |           |     1 |   204 |       |
    7  (15)| 00:00:01 |
|   8 |         TABLE ACCESS BY INDEX ROWID| RULON     |     1 |   195 |       |
    3   (0)| 00:00:01 |
|*  9 |          INDEX RANGE SCAN          | I_RUL     |     1 |       |       |
    2   (0)| 00:00:01 |
|  10 |         TABLE ACCESS FULL          | MC        |    45 |   405 |       |
    3   (0)| 00:00:01 |
|* 11 |        INDEX RANGE SCAN            | GRAPH_RUL |  3391 |       |       |
   12   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------

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

   2 - filter("VW_COL_33" IS NOT NULL)
   4 - filter(TO_DATE('02.01.2016 15:00:00','dd.mm.yy hh24:mi:ss')>=TO_DATE('2016-01-02 
              07:00:00', 'yyyy-mm-dd hh24:mi:ss'))
   7 - access("RULON"."MS"="MC"."UKEY")
   9 - access("TS">=TO_DATE('2016-01-02 07:00:00', 'yyyy-mm-dd hh24:mi:ss') AND 
              "TS"<=TO_DATE('02.01.2016 15:00:00','dd.mm.yy hh24:mi:ss'))
  11 - access("RULON"."UKEY"="GRAPH"."U_RUL")


Индекс таблиц RULON:

Таблица Индекс  Тип         Колонки
RULON   RUL_UN  UNIQUE      UKEY
RULON   I_RUL   NONUNIQUE   TS


GRAPH:

GRAPH   GRAPH_RUL   NONUNIQUE   U_RUL

    


Ответы

Ответ 1



Оптимизатор оракла походу построил максимально эффективный план для данного запроса. Он по GRAPH идет всего один раз, строя оконную функцию и выбирая по ней запись с минимальным K. Но для поиска этого минимума ему приходится пройти много записей графа и просто изменением запроса это не лечится. Как решения вижу: Хранить минимальный K к рулону (и вести его триггерами), что бы исключить необходимость поиска минимума в графе. Как минус - собственно необходимость создания триггера, который при добавлении/модификации записей в GRAPH должен будет сверять K с хранимым в рулоне и менять его там, при необходимости. Построить на GRAPH составной индекс по колонкам (U_RUL, K), тогда оракл должен сходу находить записи с минимальным K, не заглядывая в данные. Как минус - индекс на 373кк записей займет много места и несколько замедлит создание новых записей в таблице GRAPH.

Комментариев нет:

Отправить комментарий