Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> PL\SQL кэширование результатов функции, PL\SQL кэширование результатов функции 
:(
    Опции темы
Matrex
Дата 9.2.2011, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 31.1.2006

Репутация: нет
Всего: 2



Коллеги есть ли в PL/SQL какой либо механизм «кэширования результатов функции» - наверно так это можно назвать. Имеется ввиду, что если в функцию все время передаются одни и те-же параметры (по значению), то не стоит все время выполнять тело функции и рассчитывать результат, а выдавать сразу готовый ответ.

Оставим споры на счет того насколько это целесообразно, хочется получить конкретный ответ – «есть» или «нет»…

PM MAIL   Вверх
Zloxa
Дата 9.2.2011, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



В PL/SQL - наврняка нет.
В SQL, я слышал, вроде пытались что-то сделать для детерминированных функций, начиная с 10й версии.

Это сообщение отредактировал(а) Zloxa - 9.2.2011, 11:44


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Matrex
Дата 9.2.2011, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 31.1.2006

Репутация: нет
Всего: 2



Понял, спасибо за ответ...

Добавлено через 1 минуту и 6 секунд
Кстати, а как этот механизм правильно называется, дабы почитать об этом поподробнее...
PM MAIL   Вверх
Zloxa
Дата 9.2.2011, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(Zloxa @  9.2.2011,  11:42 Найти цитируемый пост)
вроде 

 smile 
Код

Connected to Oracle9i Enterprise Edition Release 9.2.0.8.0 

set echo on
set serveroutput on
create or replace function foo(bar number) return number deterministic
is
begin
 dbms_output.put_line('boo!!!');
 return null;
end;
/
 
Function created
select level, foo(1) from dual connect by level <= 3;
 
     LEVEL     FOO(1)
---------- ----------
         1 
         2 
         3 
 
boo!!!
boo!!!
boo!!!

Код

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 

select level, foo(1) from dual connect by level <= 3;
 
     LEVEL     FOO(1)
---------- ----------
         1 
         2 
         3 
 
boo!!!


Добавлено @ 11:49
Цитата(Matrex @  9.2.2011,  11:45 Найти цитируемый пост)
как этот механизм правильно называется,

 smile

Добавлено @ 11:50
Может расскажете с какой проблеммой сотолкнулись, а не как пытаетесь решать?

Добавлено через 4 минуты и 32 секунды
блин, а ведь и вправду работает   smile 
Код

select level, foo(mod(level,2)) from dual connect by level <= 6;
 
     LEVEL FOO(MOD(LEVEL,2))
---------- -----------------
         1 
         2 
         3 
         4 
         5 
         6 
 
boo!!!
boo!!!


Это сообщение отредактировал(а) Zloxa - 9.2.2011, 11:51


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Matrex
Дата 9.2.2011, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 31.1.2006

Репутация: нет
Всего: 2



А чего-ж не рассказать? – свежие идеи всегда к месту smile 

Это все продолжение моих идей на счет состава изделий и замен в составе изделий (мы когда-то говорили об этом). Я реализовал этот механизм с использованием поплайна – в некоторых случаях тормозит прилично, особенно когда ты хочешь построить одновременно состав нескольких изделий и когда выполняются «замены замен»… И это понятно – для каждого элемента выполняется функция на выборку из таблицы замен на предмет «есть ли замена»? Вот тут бы эта особенность функции и пригодилась… Сейчас рассматривается вопрос с использованием временных таблиц, ну, и попутно, другие варианты…
PM MAIL   Вверх
Zloxa
Дата 9.2.2011, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Нет, не пригодилось бы.
Это кэширование работает только для детерминированных функций - функций, зависящих только от входных параметров. Если функция зависит еще от состояния сессии, от даных в базе, от времени, она не детерменирована, и ее кеширование может исказить результат.
И это, более чем разумно. Оракле ведь не ведомо, каково то событие, которое должно сбросить кэш.
Потому, для данного случая, если есть необходимость кэшировать, придется делать это самостоятельно. И самостоятельно же сбрасывать кэш. Правда средствами pl/sql, пожалуй, кэшировать получится только в рамках сессии, не приложения.


Это сообщение отредактировал(а) Zloxa - 10.2.2011, 09:58


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Matrex
Дата 9.2.2011, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 31.1.2006

Репутация: нет
Всего: 2



Предлагаю проверить следующим образом:

Код

create or replace function foo(bar number) return number deterministic
is
i number;
n number;
begin
 n:=0;
 for i in 1..100000 loop
     n:=n+1; 
 end loop;
 
 return n;
end;


Код

select level, foo(3) from dual connect by level <= 6

выполняется 0,5 сек

Код

select level, foo(3) , foo(3) from dual connect by level <= 6

выполняется 1 сек

Т.о. получается, что каждый раз при обращении к функции цикл выполняется заново… Или я не правильно понимаю понятие «детерминированных функций»?



PM MAIL   Вверх
Zloxa
Дата 9.2.2011, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



да, так вызывается два раза
Код

select level lvl, foo(3), foo(3) from dual connect by level <= 6;
 
       LVL     FOO(3)     FOO(3)
---------- ---------- ----------
         1            
         2            
         3            
         4            
         5            
         6            
 
boo!!!
boo!!!
 
6 rows selected


Но с этим случаем как раз все ясно и давно известно что делать
Код

select lvl,foo,foo
from
(
select level lvl, foo(3) foo from dual connect by level <= 6
);
 
       LVL        FOO        FOO
---------- ---------- ----------
         1            
         2            
         3            
         4            
         5            
         6            
 
boo!!!
 
6 rows selected




--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Matrex
Дата 9.2.2011, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 31.1.2006

Репутация: нет
Всего: 2



Согласен, я привел частный случай. А когда ситуация следующая 

Код

select level, foo(level) from dual connect by level <= 6 and foo(level)>10


то как быть? Зачем функцию рассчитывать дважды? Сразу реальный пример. В системе существуют данные с уникальным идентификатором ID. Для каждого данного предусмотрено изменение статусов (Разработка=1, Производство=2, Архив=3 и т.д.). Статусы меняются во времени (т.е. некоторые данные в текущий момент могут иметь и статус "Производство" и "Архив" и "Разработка"). Задача – получить все данные на «Разработке» и текстовое описан статуса. Я делаю примерно таким образом:

Код

select а.*,  get_last_stat_doc(a.id).stattxt from detail a where get_last_stat_doc(a.id).stat=1


Если учесть, что элементы «живут» не только в таблице detail, но и в других таблицах (в программе я просто меняю таблицу на другую), то «запрос в подзапросе», имхо, не есть гут, а вот функция, сохранившая свой результат (хотя бы для данного сиквела, или для считываемый в настоящий момент линии) для одного и того же a.id, была бы кстати…

PM MAIL   Вверх
Zloxa
Дата 9.2.2011, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(Matrex @  9.2.2011,  14:24 Найти цитируемый пост)
то как быть?

так же - заворачиват в подзапрос, использовать вне его.
Цитата(Matrex @  9.2.2011,  14:24 Найти цитируемый пост)
Зачем функцию рассчитывать дважды? 

этот вопрос не может быть не  риторическим.
Цитата(Matrex @  9.2.2011,  14:24 Найти цитируемый пост)
Я делаю примерно таким образом

очевидно же, что вы делаете это совсем не так, как следует делать чтобы это было эффективно.

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

Цитата(Matrex @  9.2.2011,  14:24 Найти цитируемый пост)
 «запрос в подзапросе», имхо, не есть гут

спасибо, поржал.

Цитата(Matrex @  9.2.2011,  14:24 Найти цитируемый пост)
была бы кстати…

но этого нет, этого никто не обещал, и это реалии.
Более того, не сказал бы я что это действитлеьно нужно.

И... вы знаете, я не могу припомнить никаких других языков, которые кэшировали бы вызовы функций.


Это сообщение отредактировал(а) Zloxa - 9.2.2011, 18:22


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Matrex
Дата 9.2.2011, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 96
Регистрация: 31.1.2006

Репутация: нет
Всего: 2



Разумеется, рожденный программером свой опыт пытается и на другие сферы перенести – тем более, когда это кажется логичным, и в добавок курсы PL/SQL не посещал…

А на счет «запрос в подзапросе» - ничего не вижу смешного – когда имеется ввиду, данная конкретная задача и данный конкретный сиквел. Пока моих юзеров быстродействие не смущает – нет смысла переделывать. Кстати, вот тоже реальный пример, когда эту функцию (по определению статуса документа, из таблицы oma_stat) пришлось переделывать из-за быстродействия. Получилось нечто такое:

Код

      select m.id,
      m.обозначение,
      m.ревизия,
      m.наименование,
      m.дополнительно
      from
      (
      select u.*,max(t.datechstat) as maxdate
      from
      (
      select
      t.id,
      gm.sign As Обозначение,
      gm.revision as Ревизия,
      gm.name as Наименование,
      gr.sign||"/"||c.sign as Дополнительно
      from
      pdo_guidemodelcontent t,
      pdo_guidemodel gm,
      guide_concern c,
      guide_modelgroup gr
      where
      t.father=0
      and t.work='+inttostr(fsubid);
      and gm.dsetypes='+inttostr(fsubid1);
      and t.code_modelgroup<>0
      and t.work=c.omegacode(+)
      and t.code_modelgroup=gr.code(+)
      and gm.compcode=(t.types_dse||"-"||t.id_dse)
      ) u,
      oma_stat t
      where t.id_doc=u.id 
      group by
      u.id,
      u.Обозначение,
      u.Ревизия,
      u.Наименование,
      u.Дополнительно
      ) m,
      oma_stat b
      where m.maxdate=b.datechstat and m.id=b.id_doc 
      and b.stat=1


Результат, конечно супер – прирост производительности - на порядок, однако читаемость сиквела оставляет желать лучшего…
Ладно, мы уже переходим в оффтоп, так что пора подвязывать… Благодарю за советы. Буду копать.




PM MAIL   Вверх
Zloxa
Дата 9.2.2011, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(Matrex @  9.2.2011,  15:22 Найти цитируемый пост)
однако читаемость сиквела оставляет желать лучшего…

 smile 



--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Oracle"
Zloxa
LSD

Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:

  • при создании темы давайте ей осмысленное название, описывающее суть проблемы
  • указывайте используемую версию базы, способ соединения и язык программирования
  • при ошибках обязательно приводите код ошибки и сообщение сервера
  • приводите код в котором возникла ошибка, по возможности дайте тестовый пример демонстрирующий ошибку
  • при вставке кода используйте соответсвующие теги: [code=sql] [/code] для подсветки SQL и PL/SQL кода, [code=java] [/code] - для Java, и т.д.

  • документация по Oracle: 9i, 10g, 11g
  • книги по Oracle можно поискать здесь
  • действия модераторов можно обсудить здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Oracle | Следующая тема »


 




[ Время генерации скрипта: 0.0539 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.