execute immediate的问题(已解决,见楼底)

[复制链接]
查看11 | 回复7 | 2014-2-19 11:55:14 | 显示全部楼层 |阅读模式
写了一个存储函数
comp_sum用来测试不同列数的表查询的时间
按理说从第二遍开始,数据就在内存了,为什么查询时间和第一次相同?
exec createtab(100);
exec createtab(200);
exec createtab(300);
exec comp_sum(2,4);
init 2037
buf1 2
buf2 3
buf3 7
buf1 2
buf2 3
buf3 7
buf1 2
buf2 3
buf3 6
buf1 2
buf2 3
buf3 7
create or replace procedure
comp_sum( tm in number,tm2 in number )is
buf varchar(100):='';
buf1 varchar(100):='select sum(v1)||sum(v51)||sum(v100) from tcol100';
buf2 varchar(100):='select sum(v1)||sum(v101)||sum(v200) from tcol200';
buf3 varchar(100):='select sum(v1)||sum(v151)||sum(v300) from tcol300';
start_time number;
end_time number;
begin
--execute immediate 'alter system flush shared_pool';
--execute immediate 'alter system flush buffer_cache';
start_time := DBMS_UTILITY.get_time;
execute immediate 'truncate table tcol300';
execute immediate 'truncate table tcol200';
execute immediate 'truncate table tcol100';
inserttab2(10000*tm,100);
commit;
inserttab2(10000*tm,200);
commit;
inserttab2(10000*tm,300);
commit;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('init '||to_char(end_time-start_time));
for i in 1..tm2
loop
start_time := DBMS_UTILITY.get_time;
execute immediate buf1 into buf;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('buf1 '||to_char(end_time-start_time));
start_time := DBMS_UTILITY.get_time;
execute immediate buf2 into buf;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('buf2 '||to_char(end_time-start_time));
start_time := DBMS_UTILITY.get_time;
execute immediate buf3 into buf;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('buf3 '||to_char(end_time-start_time));
end loop;
end;
/
create or replace procedure inserttab2(rowc NUMBER,colc NUMBER)
is
buf varchar(24000):='insert into tcol'||to_char(colc)||' select level,';
begin
for i in 1..colc-1
loop
buf:=buf||'mod(level+'||to_char(i)||',1e10),';
end loop;
buf:=buf||'mod(level+'||to_char(colc)||',1e10) from dual connect by level set serverout on
SQL> exec comp_sum(4,3)
init 4189
buf1 4
buf2 6
buf3 14
buf1 3
buf2 6
buf3 13
buf1 4
buf2 6
buf3 13
PL/SQL procedure successfully completed.
SQL> exec comp_sum(3,3)
init 2763
buf1 2
buf2 5
buf3 10
buf1 3
buf2 4
buf3 10
buf1 3
buf2 4
buf3 10
PL/SQL procedure successfully completed.
SQL> exec comp_sum(2,3)
init 2330
buf1 2
buf2 3
buf3 7
buf1 1
buf2 3
buf3 7
buf1 2
buf2 3
buf3 6
PL/SQL procedure successfully completed.
SQL> exec comp_sum(1,3)
init 1400
buf1 2
buf2 1
buf3 4
buf1 1
buf2 1
buf3 3
buf1 1
buf2 1
buf3 4
PL/SQL procedure successfully completed.
SQL>
SQL> exec comp_sum(5,3)
init 4483
buf1 5
buf2 8
buf3 16
buf1 5
buf2 7
buf3 16
buf1 5
buf2 7
buf3 17
PL/SQL procedure successfully completed.
SQL>
SQL> exec comp_sum(6,3)
init 5325
buf1 6
buf2 9
buf3 21
buf1 5
buf2 9
buf3 20
buf1 5
buf2 9
buf3 20
PL/SQL procedure successfully completed.
SQL> exec comp_sum(7,3)
init 6981
buf1 6
buf2 11
buf3 23
buf1 6
buf2 11
buf3 23
buf1 6
buf2 10
buf3 23
PL/SQL procedure successfully completed.
SQL> exec comp_sum(8,3)
init 7523
buf1 8
buf2 12
buf3 27
buf1 7
buf2 12
buf3 26
buf1 7
buf2 12
buf3 26
PL/SQL procedure successfully completed.
SQL> exec comp_sum(9,3)
init 9581
buf1 8
buf2 14
buf3 30
buf1 8
buf2 14
buf3 29
buf1 8
buf2 13
buf3 30
PL/SQL procedure successfully completed.
SQL> exec comp_sum(10,3)
init 10530
buf1 9
buf2 15
buf3 34
buf1 9
buf2 15
buf3 33
buf1 8
buf2 15
buf3 33
PL/SQL procedure successfully completed.
回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
等待楼主的研究成果


回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
是不是跟楼主没有使用绑定变量有关呢?
回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
在我这不会啊?第一遍比其他慢很多。
init 2295
buf1 70
buf2 188
buf3 130
buf1 1
buf2 13
buf3 18
buf1 2
buf2 28
buf3 11
buf1 2
buf2 11
buf3 9
我看不是动态SQL的问题,你用静态SQL试试?
回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
是不是楼主的机器太好了,感觉不出来呢,关注
回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
SQL> exec comp_sum(2,4);
init 1328
buf1 2
buf2 3
buf3 8
buf1 1
buf2 3
buf3 8
buf1 2
buf2 3
buf3 8
buf1 1
buf2 2
buf3 8
PL/SQL 过程已成功完成。
SQL> alter system flush shared_pool;
系统已更改。
SQL> alter system flush buffer_cache;
系统已更改。
SQL> exec comp_sum(2,4)
init 1037
buf1 0
buf2 4
buf3 10
buf1 1
buf2 3
buf3 8
buf1 2
buf2 1
buf3 7
buf1 1
buf2 2
buf3 7
PL/SQL 过程已成功完成。
SQL> alter system flush shared_pool;
系统已更改。
SQL> alter system flush buffer_cache;
系统已更改。
SQL> exec comp_sum(2,4)
init 1058
buf1 0
buf2 3
buf3 7
buf1 2
buf2 3
buf3 6
buf1 0
buf2 2
buf3 6
buf1 2
buf2 1
buf3 8
PL/SQL 过程已成功完成。
[ 本帖最后由 hotiice 于 2008-9-26 08:58 编辑 ]
回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
create or replace procedure
comp_sum2( tm in number,tm2 in number )is
buf varchar(100):='';
buf1 varchar(100):='select sum(v1)||sum(v51)||sum(v100) from tcol100';
buf2 varchar(100):='select sum(v1)||sum(v101)||sum(v200) from tcol200';
buf3 varchar(100):='select sum(v1)||sum(v151)||sum(v300) from tcol300';
start_time number;
end_time number;
begin
--execute immediate 'alter system flush shared_pool';
--execute immediate 'alter system flush buffer_cache';
start_time := DBMS_UTILITY.get_time;
execute immediate 'truncate table tcol300';
execute immediate 'truncate table tcol200';
execute immediate 'truncate table tcol100';
inserttab2(10000*tm,100);
commit;
inserttab2(10000*tm,200);
commit;
inserttab2(10000*tm,300);
commit;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('init '||to_char(end_time-start_time));
for i in 1..tm2
loop
start_time := DBMS_UTILITY.get_time;
select sum(v1)||sum(v51)||sum(v100) into buf from tcol100;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('buf1 '||to_char(end_time-start_time));
start_time := DBMS_UTILITY.get_time;
select sum(v1)||sum(v101)||sum(v200) into buf from tcol200 ;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('buf2 '||to_char(end_time-start_time));
start_time := DBMS_UTILITY.get_time;
select sum(v1)||sum(v151)||sum(v300) into buf from tcol300;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('buf3 '||to_char(end_time-start_time));
end loop;
end;
/
SQL> exec comp_sum2(2,4)
init 617
buf1 1
buf2 2
buf3 8
buf1 1
buf2 2
buf3 6
buf1 2
buf2 1
buf3 5
buf1 1
buf2 2
buf3 6
PL/SQL 过程已成功完成。
SQL> exec comp_sum2(2,4)
init 749
buf1 1
buf2 2
buf3 6
buf1 2
buf2 1
buf3 10
buf1 1
buf2 2
buf3 8
buf1 1
buf2 2
buf3 4
PL/SQL 过程已成功完成。
[ 本帖最后由 hotiice 于 2008-9-26 09:00 编辑 ]
回复

使用道具 举报

千问 | 2014-2-19 11:55:14 | 显示全部楼层
create or replace procedure
comp_sum1( tm in number,tm2 in number )is
buf varchar(100):='';
buf1 varchar(100):='select sum(v1)||sum(v2)||sum(v3) from tcol100';
buf2 varchar(100):='select sum(v1)||sum(v2)||sum(v3) from tcol200';
buf3 varchar(100):='select sum(v1)||sum(v2)||sum(v3) from tcol300';
start_time number;
end_time number;
begin
--execute immediate 'alter system flush shared_pool';
--execute immediate 'alter system flush buffer_cache';
start_time := DBMS_UTILITY.get_time;
execute immediate 'truncate table tcol300';
execute immediate 'truncate table tcol200';
execute immediate 'truncate table tcol100';
inserttab2(10000*tm,100);
commit;
inserttab2(10000*tm,200);
commit;
inserttab2(10000*tm,300);
commit;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('init '||to_char(end_time-start_time));
for i in 1..tm2
loop
start_time := DBMS_UTILITY.get_time;
execute immediate buf1 into buf;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('buf1 '||to_char(end_time-start_time));
start_time := DBMS_UTILITY.get_time;
execute immediate buf2 into buf;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('buf2 '||to_char(end_time-start_time));
start_time := DBMS_UTILITY.get_time;
execute immediate buf3 into buf;
end_time := DBMS_UTILITY.get_time;
DBMS_OUTPUT.PUT_LINE('buf3 '||to_char(end_time-start_time));
end loop;
end;
/
SQL> set serverout on
SQL> exec comp_sum1(3,3)
init 4354
buf1 2
buf2 2
buf3 4
buf1 2
buf2 2
buf3 4
buf1 2
buf2 2
buf3 3
PL/SQL procedure successfully completed.
SQL> exec comp_sum1(5,3)
init 4625
buf1 4
buf2 4
buf3 6
buf1 3
buf2 4
buf3 5
buf1 3
buf2 4
buf3 6
PL/SQL procedure successfully completed.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行