Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
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; |
А вот так - неправильный
Код: | 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 в плане запроса 
Последний раз редактировалось: 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; |
|
|
 |
|
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|