Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Oracle > Индекс vs Переменная


Автор: setnull 17.3.2009, 15:39
Всем доброго здравия!

А что быстрее: обратиться по первичному ключу к записи и считать значение или обратиться к функции пакета, которая возвращает переменную этого пакета?

Дело в том, что необходимо производиьт безумно многократное такое обращение и интересно, не выгодно ли таким образом закешировать значение?

Спасибо!

Автор: Zloxa 17.3.2009, 15:43
Цитата(setnull @  17.3.2009,  15:39 Найти цитируемый пост)
А что быстрее: обратиться по первичному ключу к записи и считать значение или обратиться к функции пакета, которая возвращает переменную этого пакета?

Смотря откуда обращаться.
Если из PL/SQL, то, наверняка, второе
Если из SQL, то, наверняка, первое

Автор: setnull 17.3.2009, 15:47
p.s.

Много ли тратится на вызов функции и на сколько отличаются по производительности два таких вызова

Код

begin
select
from my_table
where my_fled = other_packege.get_hash_var()
end


Код

declare
  lcal_hash number;
begin
 lcal_hash := other_packege.get_hash_var()
select
from my_table
where my_fled = lcal_hash
end


в первом случае функция будет вызываться для каждой записи?

Спасибо!

Автор: Zloxa 17.3.2009, 16:26
Цитата(setnull @  17.3.2009,  15:47 Найти цитируемый пост)
в первом случае функция будет вызываться для каждой записи?

Код

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 
 
create or replace package testp
is
 function get_val return number;
end;
/
 
Package created
create or replace package body testp
is
 val number := 0;
 function get_val return number
 is
 begin
   val := val +1;
   return  val;
 end;
end;
/
 
Package body created
create table test_t as select level rn from dual connect by level <=10000;
 
Table created
exec dbms_session.reset_package;
 
PL/SQL procedure successfully completed
select count(*) from test_t where testp.get_val != rn;
 
  COUNT(*)
----------
         0
select testp.get_val-1 from dual;
 
TESTP.GET_VAL-1
---------------
          10000
exec dbms_session.reset_package;
 
PL/SQL procedure successfully completed
select count(*) from test_t where testp.get_val < 100;
 
  COUNT(*)
----------
     10000
select testp.get_val-1 from dual;
 
TESTP.GET_VAL-1
---------------
              1



Добавлено через 7 минут и 30 секунд
Цитата(setnull @  17.3.2009,  15:47 Найти цитируемый пост)
Много ли тратится на вызов функции и на сколько отличаются по производительности два таких вызова

Код

set timing on;
declare foo number;
begin
  for i in 1..100
  loop
    select count(*) into foo from test_t where testp.get_val != rn;
  end loop;
end;
/
 
PL/SQL procedure successfully completed
 
Executed in 2.187 seconds
declare foo number;
begin
  foo := testp.get_val;
  for i in 1..100
  loop
    select count(*) into foo from test_t where testp.get_val = foo;
  end loop;
end;
/
 
PL/SQL procedure successfully completed
 
Executed in 0.016 seconds

Автор: Zloxa 17.3.2009, 16:56
ЗЫ
ХОтя... я не правильный пример привел.
В твоем случае, с доступом по PK вызов будет производится один раз.
Однако переключение контекста SQL->PL/SQL таки вносит свою долю задержки
Код

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 
 
alter table test_t add constraint test_t$pk primary key (rn);
 
Table altered
set timing on
exec dbms_session.reset_package;
 
PL/SQL procedure successfully completed
 
Executed in 0.015 seconds
set serveroutput on;
declare foo number;
begin
  for i in 1..10000
  loop
     foo := testp.get_val;
    select count(*) into foo from test_t where rn = foo;
  end loop;
  dbms_output.put_line(testp.get_val-1);
end;
/
 
10000
 
PL/SQL procedure successfully completed
 
Executed in 0.328 seconds
exec   dbms_session.reset_package;
 
PL/SQL procedure successfully completed
 
Executed in 0.016 seconds
set serveroutput on;
declare foo number;
begin
  for i in 1..10000
  loop
    select count(*) into foo from test_t where testp.get_val = rn;
  end loop;
  dbms_output.put_line(testp.get_val-1);
end;
/
 
10000
 
PL/SQL procedure successfully completed
 
Executed in 0.406 seconds

Автор: setnull 18.3.2009, 11:01
Спасибо большое!!!!!!!!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)