Сообщение Re[2]: Oracle еше одна проблема. чтоб им. от 28.04.2015 15:44
Изменено 28.04.2015 15:58 MasterZiv
Здравствуйте, зиг, Вы писали:
зиг>>Итак, проблема следующая. есть Запрос, который работает медленно если в первый раз запускаешь. Вторые и последующие запуски (даже с изменением параметров запроса) уже более-менее быстрые — то есть видать что-то там оракл кладет в кэш. Хотелось бы чтоб запрос работал более стабильно!
зиг>>План вообще какой-то неинформативный как по мне — кост очень небольшой. То есть непонятно что там улучшать, оно типа и так все хорошо.
Так в чём проблема-то? Если только в этом, т.е. "кэш-не кэш" -- это вообще не проблема, и разговаривать не о чем.
О запросе и плане -- запрос непростой, и в него надо вникать, так сходу ничего не понятно, и надо знать данные и их
распределение, естественно.
Вот кстати он немного более аккуратно сформатированный:
[code SQL]
select B.* from
(select A.*, rownum as rn from
(select C.COMPANYNAME, C.COMPANYID as CLIENT, P.INSTRUMENT, P.VALID_FROM, P.FREQUENCY, P.DETAILEDFREQUENCY, cf.VAL_DATE ,
(select max(vv.val_date)
from tableE vv
where vv.REQUEST = p.PKEY and vv.VALID = 'Y' and vv.dealer=8
) as ASOF
from tableN c
inner join tableD dp on c.companyId=dp.companyId and dp.dealer=8
inner join tableC p on p.VALID = 'Y' and p.SINGLE = 'Y' and p.OWNER = c.COMPANYID
inner join VM_CALENDAR_FREQUENCIES cf on cf.FREQUENCY=p.FREQUENCY and cf.DETAILEDFREQUENCY=p.DETAILEDFREQUENCY and cf.VAL_DATE between '20150427' and '20150427' and cf.REGIONALHUB in ('ALL',c.REGIONALHUB)
inner join VM_IDS i on i.ID_KEY = P.INSTRUMENT and i.VALID = 'Y'
inner join tableA b on i.BOND = b.PKEY and b.VALID = 'Y'
inner join tableB_DEFAULT_PERMS pd on pd.dealer=12584 and pd.VALID ='Y' and
(pd.START_DATE is null or '20150427' > pd.START_DATE) and(pd.END_DATE is null or '20150727' < pd.END_DATE)
and pd.client=p.owner and ( (pd.bond_type=b.type and pd.bond_type in ('Sov','Corp','StatBody'))
or ( pd.bond_type = 'Unclassified' and (b.type not in ('Sov','Corp','StatBody') or b.type is null ) )
)
left outer join tableB_REQUEST_PERMS pm on pm.instrument = p.instrument and pm.CLIENT = p.owner
and pm.DEALER = 12584
and pm.VALID = 'Y'
and pm.request_id=p.pkey
and (pm.START_DATE is null or '20150427' > pm.START_DATE)
and(pm.END_DATE is null or '20150427' < pm.END_DATE)
where (c.ISCURRENT = 'Y' and c.ISDEALER = 'N' and c.REGIONALHUB in ('BLA', 'BLU', 'BLE', 'BBB', 'YY'))
and ((pm.permission in ('A','B','M','Y') )
or ( (pm.permission is null or pm.permission ='P') and (pd.permission in ('A','B','M','Y') ) )
)
order by c.COMPANYNAME Asc nulls first, c.COMPANYNAME, cf.VAL_DATE asc ) A
where rownum <= 30) B
where rn > 1;
[/code]
Очевидно, что в нём много альтернативных вариантов выполнения, от них нужно избавляться -- выполнять несколько разных запросов в разных случаях.
Также строковые литералы дат нужно оборачивать в to_date( но это к производительности не относится).
SARG-и только c.ISCURRENT = 'Y' and c.ISDEALER = 'N' and c.REGIONALHUB in ('BLA', 'BLU', 'BLE', 'BBB', 'YY')
Если они отбирают мало записей, то надо на них строить индексы и всё ОК,
если много -- ну, значит запрос такой.
Ну и ещё я бы уплощил бы запрос (убрал ненужные тут вложенные запросы ) или это пейджинг такой делается ? Тогда его надо на клиенте делать, а не так.
Если это не пейджинг, а аналитика, то для неё строк-то маловато, у тебя там HASH JOIN светится в куске плана -- это для 30 строк накладно,
тут можно ORDER индексом попробовать оптимизировать, и получать только 30 записей (ну или чуть больше).
зиг>ну то есть какой помощи от вас я прошу. не чтоб вы мне тут запрос переписали, или с индексами помогли — понятно что это невозможно без всех знаний всех таблиц и всего что там находится.
зиг>мне нужен совет — в каком направлении пнуть наших DBA которые базу майнтейнят. может быть тут очевидная какая-то недоработка с их стороны? типа если кост запроса небольшой а фактически выполняется он долго — значит , я не знаю, статистика там хреново обновляется например. или что-нибудь аналогичное же.
зиг>если б хотя бы план отображал действительную картину — тогда было бы уже легче инвестигировать. то есть я так понимаю проблему надо начинать решать с этой стороны?
Не похоже. Т.е. даже если статистика плоха, ты можешь всобачить HINT и статистика будет уже по-боку.
Явно тут напрашивается хинт first_rows(30), тогда может HASH JOIN уйдёт. Но надо весь план смотреть.
И сколько запрос работает в итоге ?
зиг>>Итак, проблема следующая. есть Запрос, который работает медленно если в первый раз запускаешь. Вторые и последующие запуски (даже с изменением параметров запроса) уже более-менее быстрые — то есть видать что-то там оракл кладет в кэш. Хотелось бы чтоб запрос работал более стабильно!
зиг>>План вообще какой-то неинформативный как по мне — кост очень небольшой. То есть непонятно что там улучшать, оно типа и так все хорошо.
Так в чём проблема-то? Если только в этом, т.е. "кэш-не кэш" -- это вообще не проблема, и разговаривать не о чем.
О запросе и плане -- запрос непростой, и в него надо вникать, так сходу ничего не понятно, и надо знать данные и их
распределение, естественно.
Вот кстати он немного более аккуратно сформатированный:
[code SQL]
select B.* from
(select A.*, rownum as rn from
(select C.COMPANYNAME, C.COMPANYID as CLIENT, P.INSTRUMENT, P.VALID_FROM, P.FREQUENCY, P.DETAILEDFREQUENCY, cf.VAL_DATE ,
(select max(vv.val_date)
from tableE vv
where vv.REQUEST = p.PKEY and vv.VALID = 'Y' and vv.dealer=8
) as ASOF
from tableN c
inner join tableD dp on c.companyId=dp.companyId and dp.dealer=8
inner join tableC p on p.VALID = 'Y' and p.SINGLE = 'Y' and p.OWNER = c.COMPANYID
inner join VM_CALENDAR_FREQUENCIES cf on cf.FREQUENCY=p.FREQUENCY and cf.DETAILEDFREQUENCY=p.DETAILEDFREQUENCY and cf.VAL_DATE between '20150427' and '20150427' and cf.REGIONALHUB in ('ALL',c.REGIONALHUB)
inner join VM_IDS i on i.ID_KEY = P.INSTRUMENT and i.VALID = 'Y'
inner join tableA b on i.BOND = b.PKEY and b.VALID = 'Y'
inner join tableB_DEFAULT_PERMS pd on pd.dealer=12584 and pd.VALID ='Y' and
(pd.START_DATE is null or '20150427' > pd.START_DATE) and(pd.END_DATE is null or '20150727' < pd.END_DATE)
and pd.client=p.owner and ( (pd.bond_type=b.type and pd.bond_type in ('Sov','Corp','StatBody'))
or ( pd.bond_type = 'Unclassified' and (b.type not in ('Sov','Corp','StatBody') or b.type is null ) )
)
left outer join tableB_REQUEST_PERMS pm on pm.instrument = p.instrument and pm.CLIENT = p.owner
and pm.DEALER = 12584
and pm.VALID = 'Y'
and pm.request_id=p.pkey
and (pm.START_DATE is null or '20150427' > pm.START_DATE)
and(pm.END_DATE is null or '20150427' < pm.END_DATE)
where (c.ISCURRENT = 'Y' and c.ISDEALER = 'N' and c.REGIONALHUB in ('BLA', 'BLU', 'BLE', 'BBB', 'YY'))
and ((pm.permission in ('A','B','M','Y') )
or ( (pm.permission is null or pm.permission ='P') and (pd.permission in ('A','B','M','Y') ) )
)
order by c.COMPANYNAME Asc nulls first, c.COMPANYNAME, cf.VAL_DATE asc ) A
where rownum <= 30) B
where rn > 1;
[/code]
Очевидно, что в нём много альтернативных вариантов выполнения, от них нужно избавляться -- выполнять несколько разных запросов в разных случаях.
Также строковые литералы дат нужно оборачивать в to_date( но это к производительности не относится).
SARG-и только c.ISCURRENT = 'Y' and c.ISDEALER = 'N' and c.REGIONALHUB in ('BLA', 'BLU', 'BLE', 'BBB', 'YY')
Если они отбирают мало записей, то надо на них строить индексы и всё ОК,
если много -- ну, значит запрос такой.
Ну и ещё я бы уплощил бы запрос (убрал ненужные тут вложенные запросы ) или это пейджинг такой делается ? Тогда его надо на клиенте делать, а не так.
Если это не пейджинг, а аналитика, то для неё строк-то маловато, у тебя там HASH JOIN светится в куске плана -- это для 30 строк накладно,
тут можно ORDER индексом попробовать оптимизировать, и получать только 30 записей (ну или чуть больше).
зиг>ну то есть какой помощи от вас я прошу. не чтоб вы мне тут запрос переписали, или с индексами помогли — понятно что это невозможно без всех знаний всех таблиц и всего что там находится.
зиг>мне нужен совет — в каком направлении пнуть наших DBA которые базу майнтейнят. может быть тут очевидная какая-то недоработка с их стороны? типа если кост запроса небольшой а фактически выполняется он долго — значит , я не знаю, статистика там хреново обновляется например. или что-нибудь аналогичное же.
зиг>если б хотя бы план отображал действительную картину — тогда было бы уже легче инвестигировать. то есть я так понимаю проблему надо начинать решать с этой стороны?
Не похоже. Т.е. даже если статистика плоха, ты можешь всобачить HINT и статистика будет уже по-боку.
Явно тут напрашивается хинт first_rows(30), тогда может HASH JOIN уйдёт. Но надо весь план смотреть.
И сколько запрос работает в итоге ?
Re[2]: Oracle еше одна проблема. чтоб им.
Здравствуйте, зиг, Вы писали:
зиг>>Итак, проблема следующая. есть Запрос, который работает медленно если в первый раз запускаешь. Вторые и последующие запуски (даже с изменением параметров запроса) уже более-менее быстрые — то есть видать что-то там оракл кладет в кэш. Хотелось бы чтоб запрос работал более стабильно!
зиг>>План вообще какой-то неинформативный как по мне — кост очень небольшой. То есть непонятно что там улучшать, оно типа и так все хорошо.
Так в чём проблема-то? Если только в этом, т.е. "кэш-не кэш" -- это вообще не проблема, и разговаривать не о чем.
О запросе и плане -- запрос непростой, и в него надо вникать, так сходу ничего не понятно, и надо знать данные и их
распределение, естественно.
Вот кстати он немного более аккуратно сформатированный:
Очевидно, что в нём много альтернативных вариантов выполнения, от них нужно избавляться -- выполнять несколько разных запросов в разных случаях.
Также строковые литералы дат нужно оборачивать в to_date( но это к производительности не относится).
SARG-и только c.ISCURRENT = 'Y' and c.ISDEALER = 'N' and c.REGIONALHUB in ('BLA', 'BLU', 'BLE', 'BBB', 'YY')
Если они отбирают мало записей, то надо на них строить индексы и всё ОК,
если много -- ну, значит запрос такой.
Ну и ещё я бы уплощил бы запрос (убрал ненужные тут вложенные запросы ) или это пейджинг такой делается ? Тогда его надо на клиенте делать, а не так.
Если это не пейджинг, а аналитика, то для неё строк-то маловато, у тебя там HASH JOIN светится в куске плана -- это для 30 строк накладно,
тут можно ORDER индексом попробовать оптимизировать, и получать только 30 записей (ну или чуть больше).
зиг>ну то есть какой помощи от вас я прошу. не чтоб вы мне тут запрос переписали, или с индексами помогли — понятно что это невозможно без всех знаний всех таблиц и всего что там находится.
зиг>мне нужен совет — в каком направлении пнуть наших DBA которые базу майнтейнят. может быть тут очевидная какая-то недоработка с их стороны? типа если кост запроса небольшой а фактически выполняется он долго — значит , я не знаю, статистика там хреново обновляется например. или что-нибудь аналогичное же.
зиг>если б хотя бы план отображал действительную картину — тогда было бы уже легче инвестигировать. то есть я так понимаю проблему надо начинать решать с этой стороны?
Не похоже. Т.е. даже если статистика плоха, ты можешь всобачить HINT и статистика будет уже по-боку.
Явно тут напрашивается хинт first_rows(30), тогда может HASH JOIN уйдёт. Но надо весь план смотреть.
И сколько запрос работает в итоге ?
зиг>>Итак, проблема следующая. есть Запрос, который работает медленно если в первый раз запускаешь. Вторые и последующие запуски (даже с изменением параметров запроса) уже более-менее быстрые — то есть видать что-то там оракл кладет в кэш. Хотелось бы чтоб запрос работал более стабильно!
зиг>>План вообще какой-то неинформативный как по мне — кост очень небольшой. То есть непонятно что там улучшать, оно типа и так все хорошо.
Так в чём проблема-то? Если только в этом, т.е. "кэш-не кэш" -- это вообще не проблема, и разговаривать не о чем.
О запросе и плане -- запрос непростой, и в него надо вникать, так сходу ничего не понятно, и надо знать данные и их
распределение, естественно.
Вот кстати он немного более аккуратно сформатированный:
select B.* from
(select A.*, rownum as rn from
(select C.COMPANYNAME, C.COMPANYID as CLIENT, P.INSTRUMENT, P.VALID_FROM, P.FREQUENCY, P.DETAILEDFREQUENCY, cf.VAL_DATE ,
(select max(vv.val_date)
from tableE vv
where vv.REQUEST = p.PKEY and vv.VALID = 'Y' and vv.dealer=8
) as ASOF
from tableN c
inner join tableD dp on c.companyId=dp.companyId and dp.dealer=8
inner join tableC p on p.VALID = 'Y' and p.SINGLE = 'Y' and p.OWNER = c.COMPANYID
inner join VM_CALENDAR_FREQUENCIES cf on cf.FREQUENCY=p.FREQUENCY and cf.DETAILEDFREQUENCY=p.DETAILEDFREQUENCY and cf.VAL_DATE between '20150427' and '20150427' and cf.REGIONALHUB in ('ALL',c.REGIONALHUB)
inner join VM_IDS i on i.ID_KEY = P.INSTRUMENT and i.VALID = 'Y'
inner join tableA b on i.BOND = b.PKEY and b.VALID = 'Y'
inner join tableB_DEFAULT_PERMS pd on pd.dealer=12584 and pd.VALID ='Y' and
(pd.START_DATE is null or '20150427' > pd.START_DATE) and(pd.END_DATE is null or '20150727' < pd.END_DATE)
and pd.client=p.owner and ( (pd.bond_type=b.type and pd.bond_type in ('Sov','Corp','StatBody'))
or ( pd.bond_type = 'Unclassified' and (b.type not in ('Sov','Corp','StatBody') or b.type is null ) )
)
left outer join tableB_REQUEST_PERMS pm on pm.instrument = p.instrument and pm.CLIENT = p.owner
and pm.DEALER = 12584
and pm.VALID = 'Y'
and pm.request_id=p.pkey
and (pm.START_DATE is null or '20150427' > pm.START_DATE)
and(pm.END_DATE is null or '20150427' < pm.END_DATE)
where (c.ISCURRENT = 'Y' and c.ISDEALER = 'N' and c.REGIONALHUB in ('BLA', 'BLU', 'BLE', 'BBB', 'YY'))
and ((pm.permission in ('A','B','M','Y') )
or ( (pm.permission is null or pm.permission ='P') and (pd.permission in ('A','B','M','Y') ) )
)
order by c.COMPANYNAME Asc nulls first, c.COMPANYNAME, cf.VAL_DATE asc ) A
where rownum <= 30) B
where rn > 1;
Очевидно, что в нём много альтернативных вариантов выполнения, от них нужно избавляться -- выполнять несколько разных запросов в разных случаях.
Также строковые литералы дат нужно оборачивать в to_date( но это к производительности не относится).
SARG-и только c.ISCURRENT = 'Y' and c.ISDEALER = 'N' and c.REGIONALHUB in ('BLA', 'BLU', 'BLE', 'BBB', 'YY')
Если они отбирают мало записей, то надо на них строить индексы и всё ОК,
если много -- ну, значит запрос такой.
Ну и ещё я бы уплощил бы запрос (убрал ненужные тут вложенные запросы ) или это пейджинг такой делается ? Тогда его надо на клиенте делать, а не так.
Если это не пейджинг, а аналитика, то для неё строк-то маловато, у тебя там HASH JOIN светится в куске плана -- это для 30 строк накладно,
тут можно ORDER индексом попробовать оптимизировать, и получать только 30 записей (ну или чуть больше).
зиг>ну то есть какой помощи от вас я прошу. не чтоб вы мне тут запрос переписали, или с индексами помогли — понятно что это невозможно без всех знаний всех таблиц и всего что там находится.
зиг>мне нужен совет — в каком направлении пнуть наших DBA которые базу майнтейнят. может быть тут очевидная какая-то недоработка с их стороны? типа если кост запроса небольшой а фактически выполняется он долго — значит , я не знаю, статистика там хреново обновляется например. или что-нибудь аналогичное же.
зиг>если б хотя бы план отображал действительную картину — тогда было бы уже легче инвестигировать. то есть я так понимаю проблему надо начинать решать с этой стороны?
Не похоже. Т.е. даже если статистика плоха, ты можешь всобачить HINT и статистика будет уже по-боку.
Явно тут напрашивается хинт first_rows(30), тогда может HASH JOIN уйдёт. Но надо весь план смотреть.
И сколько запрос работает в итоге ?