Oracle SQL и PL / SQL: как минимизировать время выполнения извлечения членов объекта (возвращается функцией пользователя) - PullRequest
0 голосов
/ 12 декабря 2010

Я написал функцию для получения ряда значений в представлении Oracle.Поскольку функции не могут возвращать более одного значения, я использовал объект (с подписью из 8 цифр).Это работает, но не хорошо ...

Время выполнения запроса выбора (и выбора из представления на основе этого запроса) пропорционально полученному количеству членов, то есть:

получение 1атрибут потребляет 1 секунду (это равносильно извлечению объекта WHOLE, но значение объекта невозможно использовать для отчета), извлечение 2 атрибутов занимает 2 секунды и т. д.каждый член возвращаемого объекта.Я думаю, что функция, возвращающая varray (8) чисел, также не решит проблему: восемь неявных вызовов должны быть заменены восемью явными подзапросами.Кто-нибудь может решить эту проблему?(За исключением переписывания для использования функции, возвращающей одну строку, которую я сейчас попробую сам ...)

Вот объявление типа:

create or replace type "ARD"."PAY_FINE_FR_12_" AS object
    (fed1 number
      , reg1 number
      , fed_nach number
      , reg_nach number
      , fed_upl number
      , reg_upl number
      , fed2 number
      , reg2 number);

1 Ответ

3 голосов
/ 12 декабря 2010

Я предполагаю, что вы дали значимые имена атрибутам вашего типа.В этом случае вы возвращаете не восемь чисел, а четыре пары чисел.Это предполагает возможный способ улучшения вещей.Может ли это действительно решить вашу проблему, будет зависеть от точных деталей вашей ситуации (которую вы не предоставили).

Вот тип, представляющий эти пары чисел, и тип вложенной таблицы, который мы можем использовать для обработки массива.

create or replace type pay_pair as object
    ( pay_cat varchar2(4)
      , fed number
      , reg number )
/

create or replace type pay_pair_nt as table of pay_pair
/

Это функция, которая заполняет массив четырьмя парами чисел.В отсутствие какого-либо фактического бизнес-правила я использовал самый простой пример.

create or replace function get_pay_pairs
    return pay_pair_nt
is
    return_value pay_pair_nt;
begin
    select 
        pay_pair (
            case col1 
                when 1 then 'one'
                when 2 then 'nach'
                when 3 then 'upl'
                when 4 then 'two'
                else null;
            end
            , fed
            , pay )
    bulk collect into return_value
    from v23;
    return return_value;
end;
/

Если вам нужна подпись исходного типа, вы можете переписать свою функцию следующим образом:

create or replace function get_pay_fine
    return PAY_FINE_FR_12_
is
    return_value PAY_FINE_FR_12_;
    l_array pay_pair_nt;
begin    
    l_array := get_pay_pairs;
    for i in 1..4 loop
        case l_array(i).pay_cat 
           when 'one' then
               return_value.fed1 := l_array(i).fed;
               return_value.reg1 := l_array(i).reg;
           when 'nach' then
               return_value.fed_nach := l_array(i).fed;
               return_value.reg_nach := l_array(i).reg;
           when 'upl' then
               return_value.fed_upl := l_array(i).fed;
               return_value.reg_upl := l_array(i).reg;            
           else
               return_value.fed2 := l_array(i).fed;
               return_value.reg2 := l_array(i).reg;
           end case;
        end loop;
    return return_value;
end;

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

...