“还能再快一点吗?”梁老师再次发问引发台下一片大笑,因为大家这时都认为老师是在开玩笑。
“别笑,我可不是开玩笑哦,同学们再执行这个proc3,看看有啥新发现。”
“梁老师,我看到commit了,我觉得应该放在循环的外面而不是里面。放在里面意味着每插入1条,就要提交1次,那放在循环里就要提交10万次,而放在循环外就是全部插入完后提交1次,我觉得少提交更好。”细心的小莲发现了commit 位置的不同。
“说得非常好,commit触发LGWR将REDO BUFFER写出到REDO BUFFER中,并且将回滚段的活动事务标记为不活动,同时让回滚段中记录对应前镜像记录的所在位置标记为可以重写,切记commit可不是写数据的动作哦,写数据将数据从DATA BUFFER刷出磁盘是由CKPT决定的,前面大家应该有印象。
所以commit做的事情开销并不大,单次提交可能需要0.001秒即可完成。另外不管多大批量操作后的提交,仅针对commit而言,也是做这三件事,所花费的总时间不可能超过1秒。打个比方,批量100万条更新执行后完成commit的提交可能也就需要0.8秒,但是100万×0.001的时间可是远大于1×0.8的时间了。
下面我们来做做试验,将proc3改写为proc4,具体如下:
create or replace procedure proc4
as
begin
for i in 1 .. 100000
loop
insert into t values (i);
end loop;
commit;
end;
/
----这里要记得先预先执行一遍,将过程创建起来!
脚本2-37 第3次改进,将proc3改造成提交在循环外的proc4
接下来我们继续测试proc4的性能,也是在公平的环境下操作的,如下:
SQL> drop table t purge;
表已删除。
SQL> create table t ( x int );
表已创建。
SQL> alter system flush shared_pool;
系统已更改。
SQL> set timing on
SQL> exec proc4;
PL/SQL 过程已成功完成。
已用时间: 00: 00: 02.18
SQL> select count(*) from t;
COUNT(*)
-----------------
100000
脚本2-38 第3次改进后2秒完成,汽车变动车
速度是多少?”梁老师回头看着大家。
“哇,2秒就完成了!”还是晶晶的惊叫声。
“等同于每秒5万条记录,原先可是每秒2千多条啊,不可思议!”小莲数学换算总是最快。