CftClub.ru
Клуб специалистов ЦФТ-Банк

Полезные приемы

 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Справочник PL/PLUS: Функции, примеры, приёмы
Предыдущая тема :: Следующая тема  
Автор Сообщение
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеПт Июл 22, 2011 09:55    Ответить с цитатой
Полезность: 1
Дык смотря для чего полезных...
Для разного рода утилит полезны библиотеки функций типа ::[runtime].%, пакеты stdio, utils, rtl, nav, message;
у кого РБО, то ::[dwt].%
еще конечно standard как справочник названий исключений, и "CONSTANT" как сборник констант.

Полезный прием, например:
как правило, все массивы в оракле (индексированные по числу) при массовых (балковых) операциях индексируются с 1.
Поэтому вместо
Код:
if my_array.count>0 then
   for i in my_array.first .. my_array.last
   loop
      ...
   end loop;
end if;

можно писать
Код:
for i in 1 .. my_array.count
loop
   ...
end loop;

или вообще высший пилотаж:
Код:
for i in nvl(my_array.first,1) .. nvl(my_array.last,0)
loop
   ...
end loop;


И еще: при заполнении массивов не обязательно заводить отдельную переменную под индекс:
Код:
loop
   my_array(my_array.count+1).field1 := null;
   my_array(my_array.count).field2 := 'value';
end loop;
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеПт Июл 22, 2011 10:14    Ответить с цитатой
Полезность: 1
Еще полезный прием: как правило, на типах со ссылкой обязательно присутствует индекс на поле, содержащее ссылку.
При написании запросов, содержащих это поле, автоматический анализатор плана вполне может использовать этот возможно неоптимальный индекс.

Я в таких случая выбираю поля, по которым урезаю выборку, а к остальным прибавляю 0. 0+число = число, 0+null = null. И при этом анализатор уже исключает данное поле из списка потенциальных жертв.

Аналогично для строк: ''||поле - и поле исключается из списка потенциальных жертв.

Как пример:
Код:
select a(a%rowtype) in ::[AC_FIN] all where a.[MAIN_V_ID] like '20202810%' and a.[FILIAL] = ::[BRANCH](CODE = '001');
- вот какой индекс выберет оракл - заранее неясно, так как достаточно часто у анализатора съезжает крыша.

Зато вот так выбираем правильный (и без всяких хинтов):
Код:
select a(a%rowtype) in ::[AC_FIN] all where a.[MAIN_V_ID] like '20202810%' and 0+a.[FILIAL]%id = ::[BRANCH](CODE = '001')%id;


А вот так - неправильный Smile
Код:
select a(a%rowtype) in ::[AC_FIN] all where ''||a.[MAIN_V_ID] like '20202810%' and a.[FILIAL]%id = ::[BRANCH](CODE = '001')%id;


Кстати, если поставить 0+ с обеих сторон, получим гарантированный hash_join в плане запроса Smile


Последний раз редактировалось: Random (Пт Июл 22, 2011 10:24), всего редактировалось 1 раз
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеПт Июл 22, 2011 10:20    Ответить с цитатой
Полезность: 1
Достаточно частая ошибка: использование функции в запросе. Причем не в условии, где это вообще криминал, а среди полей:
Код:
select s(sum(f.a('И'||s%id||'СН', sysdate))) in ::[AC_FIN] all


Это неэффективно, так как в данном случае есть переключение контекста SQL к контексту pl/sql, что в оракле тормозит.
Гораздо лучшее по скорости решение:
Код:
declare n number;
begin
   n:=0;
   for s in ::[AC_FIN] loop
      n := n+f.a('И'||s%id||'СН', sysdate);
   end loop;
end;
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеПт Июл 22, 2011 10:23    Ответить с цитатой
Полезность: Нет оценки
И еще полезный прием:

Гарантированный nested loop (а то ведь анализатор может и hash_join сделать):
Код:
select a(
(select b(b.[MAIN_V_ID]) in ::[AC_FIN] all where b=a.[ACCOUNT])
) in ::[PR_CRED] all;
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Справочник PL/PLUS: Функции, примеры, приёмы Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Рейтинг@Mail.ru