Re: Oracle еше одна проблема. чтоб им.
От: AVAKON  
Дата: 01.05.15 10:05
Оценка: 1 (1)
Здравствуйте, зиг,

А попробуй код, без которого все летает вынести в самый верх, туда где select B.*. Там же ограничение на вывод 30 строк идет, зачем находить максимальное значение (ASOF) целиком для всех строк? Там где сейчас ASOF вычисляется просто оставь p.PKEY, чтобы по нему уже вверху вычислить ASOF.
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 . Предыдущая версия .
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[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


Если непонятно, в чём косяк с последним вариантом — запустите любой похожий запрос и посмотрите на результаты
Re[2]: Oracle еше одна проблема. чтоб им.
От: wildwind Россия  
Дата: 28.04.15 17:15
Оценка:
Здравствуйте, зиг, Вы писали:

зиг> мне нужен совет — в каком направлении пнуть наших DBA которые базу майнтейнят. может быть тут очевидная какая-то недоработка с их стороны?


Я знаю, что вам ответят админы на любой пинок. "На продакшене нормально выполняется? Нормально. К пуговицам претензии есть? Нет. А девелопменте, ясен пень, железо не такое мощное. Скажи спасибо, что второй раз быстро выполняется."

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


Есть способы получить и действительную картину. Но для этого нужно Кайта читать.

В общем, если пользователи и DBA на этот запрос не жалуются — забейте/потерпите.
avalon/1.0.442
Re[4]: Oracle еше одна проблема. чтоб им.
От: wildwind Россия  
Дата: 28.04.15 17:15
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ> Про OR-ы в JOIN-ах вам тоже правильно сказали -- безобразие.

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

Вот вредных советов не надо сходу давать.
avalon/1.0.442
Re[3]: Oracle еше одна проблема. чтоб им.
От: Softwarer http://softwarer.ru
Дата: 28.04.15 20:33
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ> Также строковые литералы дат нужно оборачивать в to_date( но это к производительности не относится)


Гораздо лучше обернуть их в константы. Типа

cf.VAL_DATE = DATE '2015-04-27'


Это если мы не говорим про нормальные байнды, конечно.
Re[5]: Oracle еше одна проблема. чтоб им.
От: TMU_1  
Дата: 29.04.15 06:59
Оценка:
MZ>>cost лучше вообще не смотреть, я напр. даже не знаю, в каких попугаях он мериится.
MZ>>Смотреть надо на cardinality.
зиг>а как сделать чтоб кардиналити выводился?
зиг>пользуюсь pl/sql developer.



Ну тогда в окошке Explain Plan должна быть такая кнопочка с гаечным ключом — Preferences. Там все настраивается, какие значения выводить, какие нет.
Гуру, кстати, до сих по не упомянули вот какую вещь: oracle, вообще-то, не гарантирует, что реальный план выполнения запроса будет именно такой, который выдан в результате explain plan.
Окончательный диагноз дает только вскрытие Трассу надо снимать, обрабатывать tkprof и смотреть — вот там вся правда
Иногда бывают дивные отличия от explain plan.
Но это колдунство потребует чтения книжки или документации, скорее всего.
Re: Oracle еше одна проблема. чтоб им.
От: AVAKON  
Дата: 01.05.15 10:07
Оценка:
Здравствуйте, зиг,

А попробуй код, без которого все летает вынести в самый верх, туда где select B.*. Там же ограничение на вывод 30 строк идет, зачем находить максимальное значение (ASOF) целиком для всех строк? Там где сейчас ASOF вычисляется просто оставь p.PKEY, чтобы по нему уже вверху вычислить ASOF.
Re[2]: Oracle еше одна проблема. чтоб им.
От: зиг Украина  
Дата: 01.05.15 11:19
Оценка:
Здравствуйте, AVAKON, Вы писали:

AVA>Здравствуйте, зиг,


AVA>А попробуй код, без которого все летает вынести в самый верх, туда где select B.*. Там же ограничение на вывод 30 строк идет, зачем находить максимальное значение (ASOF) целиком для всех строк? Там где сейчас ASOF вычисляется просто оставь p.PKEY, чтобы по нему уже вверху вычислить ASOF.


ха! верной дорогой идете товарищи! до этого я уже сама додумалась и сделала, и запрос действительно стал летать.
НО, проблема остается если мы делаем не первые 30 строк, а все допустим, или, если по этому значению asof нам нужно фильтровать либо сортировать. тогда его выносить наружу никак нельзя.
Re[3]: Oracle еше одна проблема. чтоб им.
От: AVAKON  
Дата: 01.05.15 12:58
Оценка:
Здравствуйте, зиг, Вы писали:

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


AVA>>Здравствуйте, зиг,


AVA>>А попробуй код, без которого все летает вынести в самый верх, туда где select B.*. Там же ограничение на вывод 30 строк идет, зачем находить максимальное значение (ASOF) целиком для всех строк? Там где сейчас ASOF вычисляется просто оставь p.PKEY, чтобы по нему уже вверху вычислить ASOF.


зиг>ха! верной дорогой идете товарищи! до этого я уже сама додумалась и сделала, и запрос действительно стал летать.

зиг>НО, проблема остается если мы делаем не первые 30 строк, а все допустим, или, если по этому значению asof нам нужно фильтровать либо сортировать. тогда его выносить наружу никак нельзя.

А план, который ты кусочек прислала, он ведь уже выполнен после переброса ASOF вверх? Судя по нему это значение рассчитывается именно для 30 строк, а не для всей выборки. Может есть смысл использовать аналитику типа max over, материализовать обращение к tablee при помощи with, и потом уже с неё максимумы эти тянуть? Если не будем ограничиваться выборкой 30 строк, то имхо это может помочь. У нас же здесь тормоза, как я понимаю из-за определения этих максимумов...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.