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