Arrays PL-SQL中循环前缓存数组长度
我想知道在PL-SQL缓存中,Arrays PL-SQL中循环前缓存数组长度,arrays,oracle,caching,plsql,Arrays,Oracle,Caching,Plsql,我想知道在PL-SQL缓存中,FOR循环中使用的数组长度是否会对过程性能产生重大影响? 这个例子也是如此: ln_count := lna_avcs.COUNT; FOR i in 1..ln_count LOOP --do something END LOOP; 比这个更有效: FOR i in 1..lna_avcs.COUNT LOOP --do something END LOOP; 假设数组的维数在100到1000之间 我知道在javascript中,使用缓存的示例可以有显著的改进
FOR循环
中使用的数组长度是否会对过程性能产生重大影响?
这个例子也是如此:
ln_count := lna_avcs.COUNT;
FOR i in 1..ln_count LOOP
--do something
END LOOP;
比这个更有效:
FOR i in 1..lna_avcs.COUNT LOOP
--do something
END LOOP;
假设数组的维数在100到1000之间
我知道在javascript中,使用缓存的示例可以有显著的改进。
谢谢我做了一些性能检查,版本1和版本2之间没有任何显著差异。我重复了几次测试,结果几乎相同。有时版本1更好,有时版本2更好 出于测试目的,我创建了一个数组:
type array_t is varray(1000) of varchar2(80);
array array_t ;
然后我用虚拟数据填充数组:
select dbms_random.string('X',25)
bulk collect into array
from dual connect by level < 1000;
测试2:
for j in 1..10000 loop
for i in 1..array.count loop
temp := array(i);
end loop;
end loop;
for j in 1..10000 loop
vcount := array.COUNT;
for i in 1..vcount loop
temp := array(i);
end loop;
end loop;
我测量了执行Test1和Test2的时间
timestart := systimestamp;
--Test1 or Test2 is here
timeend := systimestamp;
diff := extract(second from timeEnd - timeStart);
我插入了diff to loop_测试表:
insert into loop_test values
(1, diff);
在那之后,我重复了每个测试200次。查询表单loop_测试为我们提供:
select id,
avg(exectime),
count(*),
max(exectime),
min(exectime)
from loop_test
group by id
ID AVG(EXECTIME) COUNT(*) MAX(EXECTIME) MIN(EXECTIME)
1 0.797545 200 1.046 0.78
2 0.79841 200 1.045 0.78
结果:
for j in 1..10000 loop
for i in 1..array.count loop
temp := array(i);
end loop;
end loop;
for j in 1..10000 loop
vcount := array.COUNT;
for i in 1..vcount loop
temp := array(i);
end loop;
end loop;
从性能角度来看,使用array.Count或首先使用分配给变量的Count之间没有显著差异。测试是在Oracle11g上完成的
完整测试如下:
declare
type array_t is varray(1000) of varchar2(80);
array array_t ;
temp varchar2(80);
timestart timestamp;
timeend timestamp;
diff number;
begin
select dbms_random.string('X',25)
bulk collect into array
from dual connect by level < 1000;
for k in 1..200 loop
timestart := systimestamp;
for j in 1..10000 loop
for i in 1..array.count loop
temp := array(i);
end loop;
end loop;
timeend := systimestamp;
diff := extract(second from timeEnd - timeStart);
dbms_output.put_line(diff || ' ' || timestart || ' ' || timeend);
insert into loop_test values
(1, diff);
commit;
end loop;
end;
声明
类型数组是varchar2(80)的varray(1000);
阵列t;
温度varchar2(80);
时间启动时间戳;
时间结束时间戳;
差异数;
开始
选择dbms_random.string('X',25)
批量收集到阵列中
通过小于1000级的双连接;
对于1..200循环中的k
timestart:=systimestamp;
对于1..10000循环中的j
对于1..array.count循环中的i
温度:=阵列(i);
端环;
端环;
TIMEND:=systimestamp;
diff:=提取(从timeEnd到timeStart的第二个);
dbms|u输出.put|u行(diff | |‘| | | | | | | | | | | timestart | | | | timeend);
插入循环测试值
(1,差异);
犯罪
端环;
结束;
一个快速的实验表明,它没有明显的区别-对于集合中的大约7000行,两种方式所用的时间都是0.06秒。好的,那么就没有理由再添加一个变量来保持计数了,即使集合是字符串或对象的集合。当然,我从未见过这样做。我几乎可以肯定,.COUNT
实际上不会执行任何程序循环来计算数组的内容;相反,它访问数组的一个属性,该属性随着数组的发展而自动保持同步。换句话说,没有必要“缓存”它。哦,很高兴知道这一点,然后比以往任何时候都清楚了,谢谢你,那么很清楚了,谢谢你花时间做这个测试,我也会在我的机器上做