Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Виснет запрос с функцией и условием  [new]
onyx2012
Member

Откуда:
Сообщений: 130
Добрый день.

Имеется простенький запрос, с использованием функции. Функция подсчитывает некоторый баланс по сделкам с партнерами и выдает результат либо со знаком минус, либо плюс, либо ноль.

Выглядит вот так:
select partner, deal_id, get_balance(deal_id) as balance
  from ...


Картинка с другого сайта.

Суть в том, что все работает прекрасно до тех пор, пока к запросу не добавить условие

select * from (
  select partner, deal_id, get_balance(deal_id) as balance
    from ...
   ) where balance > 0


После этого запрос намертво виснет. Подскажите, в чем здесь может быть дело?
Как получить результат с балансом больше нуля?

Спасибо.
2 июл 12, 10:18    [12802352]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
xtender
Member

Откуда: Мск
Сообщений: 5704
Прохинтуй с no_merge
2 июл 12, 10:28    [12802394]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
grey_narn
Member

Откуда: Алма-Ата, Казахстан
Сообщений: 178
Запрос из одной таблицы или из нескольких? Вы бы планы с предикатами выложили. Ну и может, вам no_merge хинт поможет? Хотя не уверен, спасет ли он от проталкивания предикатов.
2 июл 12, 10:30    [12802402]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
onyx2012
Member

Откуда:
Сообщений: 130
К сожалению никогда с подсказками не сталкивался, написал вот так:

select * from (
  select /*+ NO_MERGE */ partner, deal_id, get_balance(deal_id) as balance
    from ...
   ) where balance > 0


Не срабатывает.
2 июл 12, 10:43    [12802496]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
onyx2012
Member

Откуда:
Сообщений: 130
grey_narn,

да, запрос из нескольких таблиц
2 июл 12, 10:45    [12802509]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
grey_narn
Member

Откуда: Алма-Ата, Казахстан
Сообщений: 178
select /*+ NO_MERGE(t) */ * from (
  select partner, deal_id, get_balance(deal_id) as balance
    from ...
   ) t where balance > 0


а так?
2 июл 12, 10:45    [12802510]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
onyx2012
Member

Откуда:
Сообщений: 130
grey_narn,

нет, к сожалению не срабатывает
2 июл 12, 10:51    [12802545]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
onyx2012,

планы. конечно, планы.
между прочим, вполне вероятно, что вам лишь померещелось, что запрос без ограничения (f > 0 )
работает принципиально быстрее - не исключено, что он лишь быстрее откликается
2 июл 12, 10:56    [12802575]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
Corner
Member

Откуда:
Сообщений: 1270
еще хорошо б глянуть трассировку. потому что логику функции вы в плане не увидите, а в трассировке можно будет понять в каком месте проблема.
2 июл 12, 11:04    [12802618]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
onyx2012
Member

Откуда:
Сообщений: 130
Вот так все выглядит

select *
  from (select pa.paid,
               de.deid,
               get_deal_balance(de.deid) balance_rub
          from o.deal de, o.partner pa
         where de.paid = pa.paid
         group by pa.paid, de.deid)
 where balance_rub > 0


Картинка с другого сайта.
2 июл 12, 11:05    [12802627]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
Corner
Member

Откуда:
Сообщений: 1270
onyx2012

Суть в том, что все работает прекрасно до тех пор, пока к запросу не добавить условие

select * from (
  select partner, deal_id, get_balance(deal_id) as balance
    from ...
   ) where balance > 0




а план без условия другой, что ли?? и предикаты доступа тоже покажите.
И вообще лучше показывайте план из sqlplus.
2 июл 12, 11:09    [12802656]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
ORA__SQL
Member

Откуда: Moscow
Сообщений: 1774
onyx2012, rownum в помощь
select * from (
  select rownum, partner, deal_id, get_balance(deal_id) as balance
    from ...
   ) where balance > 0
2 июл 12, 11:11    [12802666]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
onyx2012
..

то есть у вас функция ( еще и) агрегативная?
2 июл 12, 11:13    [12802677]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
grey_narn
Member

Откуда: Алма-Ата, Казахстан
Сообщений: 178
onyx2012,

планы лучше в текстовом виде выкладывать. У вас даже предикатов не видно. Ну и план запроса без фильтра тоже покажите.
Ну и такой (может, для ваших данных дурной) вариант:
with t as (select pa.paid,
               de.deid,
               get_deal_balance(de.deid) balance_rub
          from o.deal de, o.partner pa
         where de.paid = pa.paid
         group by pa.paid, de.deid)
select /*+ materialize(t)*/ t.*
from t
where t.balance_rub > 0
2 июл 12, 11:13    [12802680]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
grey_narn
Member

Откуда: Алма-Ата, Казахстан
Сообщений: 178
orawish
то есть у вас функция ( еще и) агрегативная?

Аргумент функции - одно из полей в group by.
2 июл 12, 11:14    [12802689]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
grey_narn
Member

Откуда: Алма-Ата, Казахстан
Сообщений: 178
onyx2012
Вот так все выглядит

select *
  from (select pa.paid,
               de.deid,
               get_deal_balance(de.deid) balance_rub
          from o.deal de, o.partner pa
         where de.paid = pa.paid
         group by pa.paid, de.deid)
 where balance_rub > 0



Я что-то не понял... Если de.paid = pa.paid, то на кой оба эти поля вытягивать и по обоим группировать?
2 июл 12, 11:18    [12802710]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
grey_narn
Member

Откуда: Алма-Ата, Казахстан
Сообщений: 178
grey_narn
onyx2012
Вот так все выглядит

select *
  from (select pa.paid,
               de.deid,
               get_deal_balance(de.deid) balance_rub
          from o.deal de, o.partner pa
         where de.paid = pa.paid
         group by pa.paid, de.deid)
 where balance_rub > 0



Я что-то не понял... Если de.paid = pa.paid, то на кой оба эти поля вытягивать и по обоим группировать?

фигню написал, deid с paid перепутал.
2 июл 12, 11:19    [12802722]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
onyx2012
Member

Откуда:
Сообщений: 130
ORA__SQL,

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

В общем, на сейчас было решено ограничивать запрос дополнительным условием по дате. То есть брать конкретную дату сделки. В таком случае запрос, видимо, существенно сокращается и все начинает работать как надо. То есть условие where balance_rub > 0 срабатывает.

Всем большое спасибо за помощь. В будущем обязательно более подробно разберусь с этим случаем.
2 июл 12, 11:29    [12802777]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
Edward Shevtsov
Member

Откуда: Moscow
Сообщений: 13469
grey_narn
Запрос из одной таблицы или из нескольких? Вы бы планы с предикатами выложили. Ну и может, вам no_merge хинт поможет? Хотя не уверен, спасет ли он от проталкивания предикатов.


/*+ NO_PUSH_PRED */
2 июл 12, 11:53    [12802933]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
Vint
Member

Откуда: Москва
Сообщений: 4564
onyx2012,
всякой херни понаписали, а обьяснить что использовать функцию в запросе никто так и не смог)
2 июл 12, 12:00    [12802970]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
Vint
Member

Откуда: Москва
Сообщений: 4564
дурацкая привычка контролэнтер)

всякой херни понаписали, а обьяснить что использовать функцию в запросе моветон, никто так и не удосужился.
быстро у ТСа выполняется потому что возвращает только первые строки результата.
У вас тормозит функция.
перепишите без нее, все должно быть быстрее...
2 июл 12, 12:02    [12802986]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
grey_narn
Member

Откуда: Алма-Ата, Казахстан
Сообщений: 178
Edward Shevtsov
grey_narn
Запрос из одной таблицы или из нескольких? Вы бы планы с предикатами выложили. Ну и может, вам no_merge хинт поможет? Хотя не уверен, спасет ли он от проталкивания предикатов.


/*+ NO_PUSH_PRED */

если верить доке - то The NO_PUSH_PRED hint instructs the optimizer not to push a join predicate into the view. А у ТС не join predicate.
2 июл 12, 12:06    [12803008]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
Edward Shevtsov
Member

Откуда: Moscow
Сообщений: 13469
grey_narn
Edward Shevtsov
пропущено...


/*+ NO_PUSH_PRED */

если верить доке - то The NO_PUSH_PRED hint instructs the optimizer not to push a join predicate into the view. А у ТС не join predicate.
предлагаю ТС проверить и сравнить планы
2 июл 12, 12:10    [12803045]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
firehead
Member

Откуда:
Сообщений: 3
судя по запросу
select *
from (select pa.paid,
de.deid,
get_deal_balance(de.deid) balance_rub
from o.deal de, o.partner pa
where de.paid = pa.paid
group by pa.paid, de.deid)
where balance_rub > 0
Вы пытаетесь считать баланс по каждой сделке. При росте кол-ва сделок в транзакционной системе этот подход обязательно будет тормозить. В зависимости от мощности серверов это случится раньше или позже, но случится.
Вы очень правильно поступили ограничив все по дате, тогда кол-во выбираемых записей будет всегда одного порядка и не будет сильно увеличиваться с течением времени, если конечно не вырастет кол-во сделок.
2 июл 12, 14:39    [12804334]     Ответить | Цитировать Сообщить модератору
 Re: Виснет запрос с функцией и условием  [new]
onyx2012
Member

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

И тут меня осенило:

select * from (
  select decode(get_balance(deal_id), 0, null, partner) partner, deal_id,  
           get_balance(deal_id) as balance
    from ...
   ) where partner is not null


:-)
2 июл 12, 16:36    [12805383]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Oracle Ответить