ITPub博客

首页 > 应用开发 > IT综合 > CURSOR的测试(来自TOM)

CURSOR的测试(来自TOM)

原创 IT综合 作者:chance2000 时间:2006-09-03 22:08:53 0 删除 编辑
通过以下例子可以明白在为什么显式游标好像比隐式游标运行得更快了。当使用显式游标进行测试的时候,只取一次数据X=1,为了找到答案,查询只需要扫描非常少的块(很少的一致的读次数)。然而,只要使显式游标来进行隐式游标的工作,检查确保没有其他记录满足同一条件,你就会看到显式游标检查表中的每一个块。现在,接着说隐式游标,通过使用ROWNUM=1看看它是否也会在找到第一条符合条件的记录时停下来,它和显式游标做相同的工作量。当它检查表中的第二行是否符合条件时,你会看到它同显式游标一样进行相同次数的一致读;它也不得不对表进行全面扫描以核定只有一行X=1。
最有趣的是当我查询X=29,000的时候。因为那行接近表的"结尾",所以无论我采用什么方法,两个查询的工作量都差不多。为了找到满足条件的第一行它们都必须扫描几乎整个表。
现在,如果在X上有一个索引,两个查询都会使用索引范围扫描,而且两个查询都不必对表进行全面扫描,便能快速地发现只有一行满足条件。
这就解释了你的游标行为:SELECT INTO检查第二行,但显式游标却不这么做。如果你对应地进行比较:第二次显式地取数据或者把"rownum = 1"添加到SELECT INTO语句中--你就会发现两个游标的工作量相同。
简而言之,隐式游标更好。它们比使用显式游标的相同代码运行地更快,更容易编码(需要键入的代码更少),而且我个人认为使用隐式游标的代码更容易读也更容易理解。[@more@]--游标(Cursor)的测试
set serveroutput on
declare
l_last_cgets number default 0;
l_x number;
cursor c(p_x in number) is
select x from t where x = p_x;
procedure cgets(p_msg in varchar2)
is
l_value number;
begin
select b.value into l_value
from v$statname a,v$mystat b
where a.statistic# = b.statistic#
and a.name = 'consistent gets';
dbms_output.put_line(p_msg);
dbms_output.put_line('Incremental cgets: ' ||
to_char(l_value - l_last_cgets,'999,999'));
l_last_cgets := l_value;
end;
begin
cgets('Starting...');
open c(1);
fetch c into l_x;
close c;
cgets('Explicit to find X = 1 stop at first hit');

open c(1);
fetch c into l_x;
fetch c into l_x;
close c;
cgets('Explicit to find X = 1 check for dups');

select x into l_x from t where x = 1 and rownum = 1;
cgets('Implicit to find X = 1 stop at first hit rownum = 1');

select x into l_x from t where x = 1 and rownum < 2;
cgets('Implicit to find X = 1 stop at first hit rownum < 2');

select x into l_x from t where x = 1;
cgets('Implicit to find X = 1 check for dups');

open c(15000);
fetch c into l_x;
close c;
cgets('Explicit to find X = 15000 stop at first hit');

select x into l_x from t where x = 15000 and rownum = 1;
cgets('Implicit to find X = 15000 stop at first hit rownum = 1');

select x into l_x from t where x = 15000 and rownum < 2;
cgets('Implicit to find X = 15000 stop at first hit rownum < 2');

select x into l_x from t where x = 15000;
cgets('Implicit to find X = 15000 stop at first hit');

open c(29000);
fetch c into l_x;
close c;
cgets('Explicit to find X = 29000 stop at first hit');

select x into l_x from t where x = 29000;
cgets('Implicit to find X = 29000 stop at first hit');
end;
/

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/802415/viewspace-862734/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    78
  • 访问量
    835324