Oracle еше одна проблема. чтоб им.
От: зиг Украина  
Дата: 28.04.15 09:55
Оценка:
Внимание, опубликую и запрос и ПЛАН сразу. хрен вам они помогут только гагага.
Итак, проблема следующая. есть Запрос, который работает медленно если в первый раз запускаешь. Вторые и последующие запуски (даже с изменением параметров запроса) уже более-менее быстрые — то есть видать что-то там оракл кладет в кэш. Хотелось бы чтоб запрос работал более стабильно!
План вообще какой-то неинформативный как по мне — кост очень небольшой. То есть непонятно что там улучшать, оно типа и так все хорошо.
Запрос:
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


  План (частичка, ибо длинный):
Re: Oracle еше одна проблема. чтоб им.
От: зиг Украина  
Дата: 28.04.15 10:00
Оценка:
Здравствуйте, зиг, Вы писали:

зиг>Внимание, опубликую и запрос и ПЛАН сразу. хрен вам они помогут только гагага.

зиг>Итак, проблема следующая. есть Запрос, который работает медленно если в первый раз запускаешь. Вторые и последующие запуски (даже с изменением параметров запроса) уже более-менее быстрые — то есть видать что-то там оракл кладет в кэш. Хотелось бы чтоб запрос работал более стабильно!
зиг>План вообще какой-то неинформативный как по мне — кост очень небольшой. То есть непонятно что там улучшать, оно типа и так все хорошо.

ну то есть какой помощи от вас я прошу. не чтоб вы мне тут запрос переписали, или с индексами помогли — понятно что это невозможно без всех знаний всех таблиц и всего что там находится.
мне нужен совет — в каком направлении пнуть наших DBA которые базу майнтейнят. может быть тут очевидная какая-то недоработка с их стороны? типа если кост запроса небольшой а фактически выполняется он долго — значит , я не знаю, статистика там хреново обновляется например. или что-нибудь аналогичное же.
если б хотя бы план отображал действительную картину — тогда было бы уже легче инвестигировать. то есть я так понимаю проблему надо начинать решать с этой стороны?
Re: Oracle еше одна проблема. чтоб им.
От: Milena США  
Дата: 28.04.15 14:54
Оценка:
Здравствуйте, зиг, Вы писали:

зиг>Запрос:

зиг>
зиг>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

Опишу свои мысли:
Несколько таблиц, вероятно больших, джойнятся между собой, а потом результат сильно усекается условиями, т.е. получается, например, 2.000X2.000=4.000.000 строк и потом условия по этому множеству дают всего 200 строчек, то есть 99% данных, выбранных из базы, на которые было истрачено время, просто выкидываются. Вместо этого проще перебрать условиями каждую из таблиц и потом джойнить маленькие остатки. Будет в разы быстрее. Например, вот этот кусок:
[sql]
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 ) )

должен выглядеть так:
inner join 
    (
     select pd.client /* и может еще колонки, нужные для финальной таблицы */
    from 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.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 ) ) 
    ) as pd  on pd.client=p.owner
Re: Oracle еше одна проблема. чтоб им.
От: londinium Украина  
Дата: 28.04.15 14:54
Оценка:
Здравствуйте, зиг, Вы писали:

зиг>Внимание, опубликую и запрос и ПЛАН сразу. хрен вам они помогут только гагага.

зиг>Итак, проблема следующая. есть Запрос, который работает медленно если в первый раз запускаешь. Вторые и последующие запуски (даже с изменением параметров запроса) уже более-менее быстрые — то есть видать что-то там оракл кладет в кэш. Хотелось бы чтоб запрос работал более стабильно!
зиг>План вообще какой-то неинформативный как по мне — кост очень небольшой. То есть непонятно что там улучшать, оно типа и так все хорошо.
зиг>Запрос:
зиг>
зиг>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

зиг>


зиг>
  План (частичка, ибо длинный):
зиг>Image: plan2.png


Вы позлобствовать пришли или как?
Я бы за такие джойны
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......
руки отбил сразу
Re: Oracle еше одна проблема. чтоб им.
От: MasterZiv СССР  
Дата: 28.04.15 15:01
Оценка:
Здравствуйте, зиг, Вы писали:

зиг>Внимание, опубликую и запрос и ПЛАН сразу. хрен вам они помогут только гагага.

зиг>Итак, проблема следующая. есть Запрос, который работает медленно если в первый раз запускаешь. Вторые и последующие запуски (даже с изменением параметров запроса) уже более-менее быстрые — то есть видать что-то там оракл кладет в кэш. Хотелось бы чтоб запрос работал более стабильно!

Это нормальная ситуация, ничего страшного в этом нет.
Это не значит, что запрос работает нестабильно.

зиг>План вообще какой-то неинформативный как по мне — кост очень небольшой. То есть непонятно что там улучшать, оно типа и так все хорошо.


Вполне возможно, что улучшать нечего.

зиг>[cut=План (частичка, ибо длинный):]


Частичка -- это всё равно что нет плана.
Выложи план в текстовом виде, но ВЕСЬ, его можно там получить.
Re[2]: Oracle еше одна проблема. чтоб им.
От: зиг Украина  
Дата: 28.04.15 15:18
Оценка:
Здравствуйте, londinium, Вы писали:

L>Вы позлобствовать пришли или как?

L>Я бы за такие джойны
L>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......
L>руки отбил сразу

для начала допустите что код писала не я и прекратите злобствтовать сами.
почему руки отбивать — из-за того что такие джойны плохо читаются или такие джойны на производительность _в ОРАКЛЕ_ влияет?
Re[2]: Oracle еше одна проблема. чтоб им.
От: зиг Украина  
Дата: 28.04.15 15:23
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Здравствуйте, зиг, Вы писали:


зиг>>Внимание, опубликую и запрос и ПЛАН сразу. хрен вам они помогут только гагага.

зиг>>Итак, проблема следующая. есть Запрос, который работает медленно если в первый раз запускаешь. Вторые и последующие запуски (даже с изменением параметров запроса) уже более-менее быстрые — то есть видать что-то там оракл кладет в кэш. Хотелось бы чтоб запрос работал более стабильно!
MZ>Это нормальная ситуация, ничего страшного в этом нет.
MZ>Это не значит, что запрос работает нестабильно.
мне кажется тут однозначно что-то не так. Еще заметки: в разных енвайронментах этот запрос работает по-разному. на продакшне лучше всего, а вот на девовском енв вообще супер медленно. hardware одинаковый
прямо чешется за что-нибудь напинать DBAщиков, такое ощущение что это во всем они виноваты. но мне нужны конкретные факты и обоснованные подозрения прежде чем к ним идти.

MZ>Частичка -- это всё равно что нет плана.

MZ>Выложи план в текстовом виде, но ВЕСЬ, его можно там получить.
дело в том что самая гигантская таблица — это tableE, которая как раз вверху плана. ну и тотал кост тоже же виден. остальные таблицы настолько маленькие что ими всеми можно пренебречь. Алсо, если убрать вот эту подлую часть с этой таблицей Е:
( select max(vv.val_date)        from tableE vv
  where vv.REQUEST = p.PKEY and vv.VALID = 'Y' and vv.dealer=8
  ) as ASOF

то запрос начинает летать (ну как бы что и ожидалось).

И вообще меня больше волнует почему запрос работает медленно а кост у плана быстрый? разве тут не что-то не так?
Re[2]: Oracle еше одна проблема. чтоб им.
От: зиг Украина  
Дата: 28.04.15 15:28
Оценка:
Здравствуйте, Milena, Вы писали:

M>Опишу свои мысли:

M>Несколько таблиц, вероятно больших, джойнятся между собой, а потом результат сильно усекается условиями, т.е. получается, например, 2.000X2.000=4.000.000 M>строк и потом условия по этому множеству дают всего 200 строчек, то есть 99% данных, выбранных из базы, на которые было истрачено время, просто M>выкидываются. Вместо этого проще перебрать условиями каждую из таблиц и потом джойнить маленькие остатки. Будет в разы быстрее. Например, вот этот кусок:

поняла вашу мысль. дело в том что я всегда думала что оракл не дурак и сам может оценить что вот по этим условиям вернется мало результатов, поэтому можно заранее их выполнить отдельно, а джойнить уже потом.
то есть оракл выступает не тупо интерпертатором того что написано в запросе и НЕ выполняет все согласно тому порядку в каких скобочках там что написал программист. а вначале анализирует запрос, и выполняет его все равно так как захочет. ну и погода на марсе

но я попробую поприменять это на практике..

ну и все равно в данном случае там все таблицы сравнительно маленькие кроме одной — tableE , и вся медленность возникает из-за этого кусочка:
(select max(vv.val_date)        from tableE vv
  where vv.REQUEST = p.PKEY and vv.VALID = 'Y' and vv.dealer=8
) as ASOF

если его убрать то все летает
Re[2]: Oracle еше одна проблема. чтоб им.
От: MasterZiv СССР  
Дата: 28.04.15 15:44
Оценка:
Здравствуйте, зиг, Вы писали:

зиг>>Итак, проблема следующая. есть Запрос, который работает медленно если в первый раз запускаешь. Вторые и последующие запуски (даже с изменением параметров запроса) уже более-менее быстрые — то есть видать что-то там оракл кладет в кэш. Хотелось бы чтоб запрос работал более стабильно!

зиг>>План вообще какой-то неинформативный как по мне — кост очень небольшой. То есть непонятно что там улучшать, оно типа и так все хорошо.

Так в чём проблема-то? Если только в этом, т.е. "кэш-не кэш" -- это вообще не проблема, и разговаривать не о чем.

О запросе и плане -- запрос непростой, и в него надо вникать, так сходу ничего не понятно, и надо знать данные и их
распределение, естественно.
Вот кстати он немного более аккуратно сформатированный:

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 уйдёт. Но надо весь план смотреть.

И сколько запрос работает в итоге ?
Отредактировано 28.04.2015 15:58 MasterZiv . Предыдущая версия .
Re[2]: Oracle еше одна проблема. чтоб им.
От: Sinix  
Дата: 28.04.15 15:47
Оценка:
Здравствуйте, londinium, Вы писали:

L>Я бы за такие джойны


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 ...... )

L>руки отбил сразу

По-моему, это автосгенеренный запрос, т.е. поддерживать сам sql никто не собирается. Если нет — то это ппц конечно.

Ну а если автосгенеренный — что там в условиях в джойне такого страшного?
Оптимизатор в последних версия MS SQL такие извраты вполне нормально прожёвывает, планы условий джойна в from clause и в where clause как правило не отличаются.
С ораклом давно не работал, он менее терпим к записи условий как попало?

Единственно, если кто-то сдуру заменит inner на outer... от тогда руки действительно отрывать надо
Re[3]: Oracle еше одна проблема. чтоб им.
От: MasterZiv СССР  
Дата: 28.04.15 15:48
Оценка:
Здравствуйте, зиг, Вы писали:

зиг>дело в том что самая гигантская таблица — это tableE, которая как раз вверху плана. ну и тотал кост тоже же виден.


Да он не очень и информативен. (total cost)

остальные таблицы настолько маленькие что ими всеми можно пренебречь. Алсо, если убрать вот эту подлую часть с этой таблицей Е:
зиг>
зиг>( select max(vv.val_date)        from tableE vv
зиг>  where vv.REQUEST = p.PKEY and vv.VALID = 'Y' and vv.dealer=8
зиг>  ) as ASOF
зиг>

зиг>то запрос начинает летать (ну как бы что и ожидалось).

Если в этой огромной таблице
tableE vv

на условия vv.REQUEST = p.PKEY and vv.VALID = 'Y' and vv.dealer=8
есть индекс и там мало записей по этому условию, то ничего страшного в этом нет.

зиг>И вообще меня больше волнует почему запрос работает медленно а кост у плана быстрый? разве тут не что-то не так?


cost лучше вообще не смотреть, я напр. даже не знаю, в каких попугаях он мериится.
Смотреть надо на cardinality.
Re[3]: Oracle еше одна проблема. чтоб им.
От: MasterZiv СССР  
Дата: 28.04.15 15:53
Оценка:
Здравствуйте, зиг, Вы писали:

MZ>>Это не значит, что запрос работает нестабильно.

зиг>мне кажется тут однозначно что-то не так.

Напротив, на этот счёт можете успокоится.
Стандартное 100% предстазуемое и неизбежное поведение.
Что два разных сервера работают по-разному -- тоже не сюрприз, разные данные -- разные планы.
Re[3]: Oracle еше одна проблема. чтоб им.
От: MasterZiv СССР  
Дата: 28.04.15 15:57
Оценка:
Здравствуйте, зиг, Вы писали:


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


Оракл -- не дурак. Можешь на этот счёт даже не беспокоиться.

Фактически совет тот процитированный -- общее место, которое может иметь место (извиняюсь за тавтологию) в данном случае, а может и не иметь.
Чтобы это проверить, надо по шагам плана идти от первого к последнему и смотреть cardinality на входе шага.
Если оно прыгает вверх, а потом вниз -- да, это оно. Если нет -- то нет.

т.е. в результате всеё равно надо смотреть план, данные и думать.

Про OR-ы в JOIN-ах вам тоже правильно сказали -- безобразие.
Надо их убирать. Проверяешь условие (на PL/SQL), и выполняешь такой запрос или другой.

Или генерация кода запроса в виде текста и EXECUTE IMEDIATE.
Re[4]: Oracle еше одна проблема. чтоб им.
От: зиг Украина  
Дата: 28.04.15 15:59
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Да он не очень и информативен. (total cost)

поняла спс

MZ>остальные таблицы настолько маленькие что ими всеми можно пренебречь. Алсо, если убрать вот эту подлую часть с этой таблицей Е:

зиг>>
зиг>>( select max(vv.val_date)        from tableE vv
зиг>>  where vv.REQUEST = p.PKEY and vv.VALID = 'Y' and vv.dealer=8
зиг>>  ) as ASOF
зиг>>

зиг>>то запрос начинает летать (ну как бы что и ожидалось).

MZ>Если в этой огромной таблице

MZ>tableE vv
MZ>на условия vv.REQUEST = p.PKEY and vv.VALID = 'Y' and vv.dealer=8
MZ>есть индекс и там мало записей по этому условию, то ничего страшного в этом нет.
есть индекс, а на каждый отдельный vv.request — ну тяжело сказать мало или не мало. 5000 это мало?

MZ>cost лучше вообще не смотреть, я напр. даже не знаю, в каких попугаях он мериится.

MZ>Смотреть надо на cardinality.
а как сделать чтоб кардиналити выводился?
пользуюсь pl/sql developer.
Re: Oracle еше одна проблема. чтоб им.
От: 11molniev  
Дата: 28.04.15 16:16
Оценка: :)
Здравствуйте, зиг, Вы писали:

зиг>Внимание, опубликую и запрос и ПЛАН сразу. хрен вам они помогут только гагага.

Довольно интересное отношение к аудитории. Попробую ответить в том же ключе.

зиг>Итак, проблема следующая. есть Запрос, который работает медленно если в первый раз запускаешь. Вторые и последующие запуски (даже с изменением параметров запроса) уже более-менее быстрые — то есть видать что-то там оракл кладет в кэш. Хотелось бы чтоб запрос работал более стабильно!


Внезапно, для таких убогих запросов так быть и должно.

Для тех, кто одарён ничего не знает о СУБД:
Когда СУБД получает запрос на SQL она не знает что с ним делать — может у вас есть индексы, может вы выбираете 100% записей из таблиц и т.д. Что бы понять, как оптимальным образом применить ресурсы сервера к именно вашим данным (ориентируясь на структуру запроса, статистики, структуру данных) СУБД строит кучу планов запросов соответствующих вашему SQL запросу и пытается найти наилучший из них. Прекращается это действо когда он найден (если запрос нормальный) или по таймауту (если запрос как выше + примерно тоже в структуре таблиц) когда найден квази оптимальный план. Когда вы выполняете запрос повторно, хотя возможно и с другими данными — наилучший план запроса уже найден и если он подходит (нет кардинальных отличий в селективности) то используется. Поэтому первый запрос выполняется медленней последующих.

Другой вопрос, что у нормальных DBA при вменяемых данных и запросах такого не происходит, поскольку число потенциальных планов мало ==> их перебор оказываться незаметен.

Как решить: проанализировать, на чем спотыкается оптимизатор и:
1. Упростить запрос (выше пример давали) сохранив его суть.
2. Добавить метаданные (индексы, статистику и т.д.) — кто его знает, что у вас в базе твориться
3. Добавить хинты (не ваш случай)
4. Обновить статистики
5. Прочитать наконец то книжку Тома Кайта.

Поскольку вы указываете на разницу между боевыми серверами и серверами разработки советую обратить внимание на 4 пункт, часто спотыкаются на нем.
Если планируете пользоваться инструментом, то его не плохо бы изучить, с этим может помочь пункт 5.
Отредактировано 28.04.2015 17:09 m2l . Предыдущая версия .
Re[2]: Oracle еше одна проблема. чтоб им.
От: зиг Украина  
Дата: 28.04.15 16:23
Оценка:
Здравствуйте, 11molniev, Вы писали:

1>Как решить: проанализировать, на чем спотыкается оптимизатор и:

1>1. Упростить запрос (выше пример давали) сохранив его суть.
чей конкретно пример вы имеете ввиду?

1>2. Добавить метаданные (индексы, статистику и т.д.) — кто его знает, что у вас в базе твориться

индексы все есть, статистика наверное должна вестись

1>3. Добавить хинты (не ваш случай)

наверное не наш, т.к. судя по плану индексы уже нужные используются

1>4. Обносить статистики

1>5. Прочитать наконец то книжку Тома Кайта.

1>Поскольку вы указываете на разницу между боевыми серверами и серверами разработки советую обратить внимание на 4 пункт, часто спотыкаются на нем.

1>Если планируете пользоваться инструментом, то его не плохо бы изучить, с этим может помочь пункт 5.

а что такое "Обносить статистики", как это по английски будет? пункт 5 мне без надобности, все равно меня к серверам и не допустят, у меня правов нет да я и не испытываю желания этим заниматься, у нас специальные люди для этого. только их надо пинать. щас вот пойду попинаю только скажите как будет по англиски.

а вообще погодите, вот вы там написали что происходит это все потому что оптимизатор пытается перебирает ищет нужный план выполнения. Но, когда я в сиквель девелопере запускаю просто посмотреть план запроса (тот самый который я в первом сообщение демонстрировала) — он его показывает мгновенно. какже так? противоречьице?
Re[4]: Oracle еше одна проблема. чтоб им.
От: зиг Украина  
Дата: 28.04.15 16:37
Оценка:
Здравствуйте, MasterZiv, Вы писали:

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

MZ>Оракл -- не дурак. Можешь на этот счёт даже не беспокоиться.
хыхы

MZ>Фактически совет тот процитированный -- общее место, которое может иметь место (извиняюсь за тавтологию) в данном случае, а может и не иметь.

MZ>Чтобы это проверить, надо по шагам плана идти от первого к последнему и смотреть cardinality на входе шага.


MZ>Если оно прыгает вверх, а потом вниз -- да, это оно. Если нет -- то нет.

MZ>т.е. в результате всеё равно надо смотреть план, данные и думать.
MZ>Про OR-ы в JOIN-ах вам тоже правильно сказали -- безобразие.
ааа, так это было про ОР-ы.. а чем они плохи? влияют на производительность?

MZ>Надо их убирать. Проверяешь условие (на PL/SQL), и выполняешь такой запрос или другой.

а как это, не поняла?
Re[3]: Oracle еше одна проблема. чтоб им.
От: зиг Украина  
Дата: 28.04.15 16:41
Оценка:
Здравствуйте, Sinix, Вы писали:

S>По-моему, это автосгенеренный запрос, т.е. поддерживать сам sql никто не собирается. Если нет — то это ппц конечно.

S>Ну а если автосгенеренный — что там в условиях в джойне такого страшного?
S>Оптимизатор в последних версия MS SQL такие извраты вполне нормально прожёвывает, планы условий джойна в from clause и в where clause как правило не отличаются.
S>С ораклом давно не работал, он менее терпим к записи условий как попало?

S>Единственно, если кто-то сдуру заменит inner на outer... от тогда руки действительно отрывать надо

извините что вклиниваюсь в вашу беседы про отрубание рук — а чем именно так плохи условия в данном запросе? при условии что таблица о которой речь крошечная (сравнительно). ну и в данном случае иннер с аутером будут одинаково работать.
Re[3]: Oracle еше одна проблема. чтоб им.
От: 11molniev  
Дата: 28.04.15 16:52
Оценка:
Здравствуйте, зиг, Вы писали:

1>>1. Упростить запрос (выше пример давали) сохранив его суть.

зиг>чей конкретно пример вы имеете ввиду?
Эта ветка: http://rsdn.ru/forum/db/6030605
Автор: зиг
Дата: 28.04.15


1>>2. Добавить метаданные (индексы, статистику и т.д.) — кто его знает, что у вас в базе твориться

зиг>индексы все есть, статистика наверное должна вестись
Важен не факт наличия индексов, а как они используются запросами.
Статистика то есть, вопрос в том насколько она актуальна.

1>>3. Добавить хинты (не ваш случай)

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

1>>4. Обносить статистики


1>>Поскольку вы указываете на разницу между боевыми серверами и серверами разработки советую обратить внимание на 4 пункт, часто спотыкаются на нем.

1>>Если планируете пользоваться инструментом, то его не плохо бы изучить, с этим может помочь пункт 5.

зиг>а что такое "Обносить статистики", как это по английски будет? пункт 5 мне без надобности, все равно меня к серверам и не допустят, у меня правов нет да я и не испытываю желания этим заниматься, у нас специальные люди для этого. только их надо пинать. щас вот пойду попинаю только скажите как будет по англиски.

Опечатка: обновить. Update statistics.
Книжка нужна, для понимания последствий своих запросов.

зиг>а вообще погодите, вот вы там написали что происходит это все потому что оптимизатор пытается перебирает ищет нужный план выполнения. Но, когда я в сиквель девелопере запускаю просто посмотреть план запроса (тот самый который я в первом сообщение демонстрировала) — он его показывает мгновенно. какже так? противоречьице?

Мало исходных данных.
Если такой запрос уже выполнялся (в том числе с другими данными) — план вы получили из описанного кеша ("аилучший план запроса уже найден и если он подходит то используется").
Если такого запрос не выполнялось, план получаем сразу, а первый запрос к реальным данным отрабатывает медленно ==> холодная база. Еще более канонический случай. Блоки данных которые надо прочесть отсутствуют в памяти (ещё не разу не читались с момента старта базы или были вытеснены более востребованными) — следствие их чтение из файлов/ASM, при последующих запросах, пока не будут вытеснены будут читаться из памяти ==> быстро.
Отредактировано 28.04.2015 17:09 m2l . Предыдущая версия .
Re[4]: Oracle еше одна проблема. чтоб им.
От: Sinix  
Дата: 28.04.15 17:14
Оценка:
Здравствуйте, зиг, Вы писали:


S>>Единственно, если кто-то сдуру заменит inner на outer... от тогда руки действительно отрывать надо

зиг> чем именно так плохи условия в данном запросе? при условии что таблица о которой речь крошечная (сравнительно).
Потому что запрос очень сложно поддерживать будет. Если код одноразовый или генерируется автоматически — всё ещё куда ни шло. Иначе тут целое поле граблей.


S>ну и в данном случае иннер с аутером будут одинаково работать.

для затравки:
SELECT * FROM A
  INNER JOIN B ON A.Id = B.A_id
  WHERE A.Name = '123'           -- OK
-- =>
SELECT * FROM A
  LEFT JOIN B ON A.Id = B.A_id
  WHERE A.Name = '123'           -- OK


-- vs

SELECT * FROM A
  INNER JOIN B ON A.Id = B.A_id
    AND A.Name = '123'           -- so-so
-- =>
SELECT * FROM A
  LEFT JOIN B ON A.Id = B.A_id
    AND A.Name = '123'           -- oops


Если непонятно, в чём косяк с последним вариантом — запустите любой похожий запрос и посмотрите на результаты
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.