- 论坛徽章:
- 3
|
本帖最后由 osdba 于 2011-02-22 19:57 编辑
我仔细看了你存储过程,发现慢的原因是你使用了一张表sno做记数器使用:
while j <= 3 do
select sno into vsno from sno;
set vsno = vsno + 1 ;
update sno set sno = vsno ;
insert into trans(trans_no,partno,qty)
values(vsno, vpartno, vonhand);
set j = j + 1;
end while ;
由于在PostgreSQL中,没有回滚段,多次对sno做更新,实际上,每更新一次,会生成一个新的版本行,同时由于你更新这个表sno是在一个事务中的,所以vacuum不会清理这个表,最后这个表中虽然只有一条记录,但这个表最终会变成3M大小,这样每次更新时找到这条记录会很慢,这导致了性能的大大下降。所以在PostgreSQL最好不要这样使用表做这样的记数器。可以使用sequence做记数器。
最终在PostgreSQL中的测试代码如下:
CREATE TABLE stocks
(
partno character varying(16) NOT NULL,
descr character varying(50),
onhand numeric(14,4),
price numeric(14,4),
CONSTRAINT pk_partno PRIMARY KEY (partno)
);
CREATE TABLE trans
(
trans_no character varying(20) NOT NULL,
partno character varying(20) NOT NULL,
qty numeric(14,4),
CONSTRAINT pk_trans PRIMARY KEY (trans_no, partno)
);
CREATE SEQUENCE seq_sno start with 1 CACHE 100;
create or replace function test() RETURNS VOID AS
$$
declare
i int;
j int;
rec int;
vsno int;
stime int;
etime int;
vpartno varchar(16);
vonhand int;
vprice numeric(10,2);
BEGIN
delete from stocks;
delete from trans;
update sno set sno = 1 ;
rec := 1;
i := rec;
while i <= rec+100000 loop
vpartno := i;
vonhand := round(random() *1000);
vprice := random() * 100;
insert into stocks(partno,descr,onhand,price)
values(vpartno, 'ABCDE', vonhand, vprice);
j := 1;
while j <= 3 loop
select nextval('seq_sno') into vsno;
vsno := vsno + 1 ;
insert into trans(trans_no,partno,qty) values(vsno, vpartno, vonhand);
j := j + 1;
end loop;
i := i + 1;
end loop;
end;
$$
LANGUAGE plpgsql;
改成这样后,测试:
osdba=# select test();
LOG: checkpoints are occurring too frequently (18 seconds apart)
HINT: Consider increasing the configuration parameter "checkpoint_segments".
test
------
(1 row)
Time: 24059.938 ms
可以看到只需要24秒就完成了这个操作。
同样在MySQL中执行你那段代码所需要的时间为73秒:
mysql> call test();
Query OK, 0 rows affected, 65535 warnings (1 min 13.39 sec)
当然由于MySQL中没有sequence,所以只能使用表做记数器,所以慢了一些。
这个测试就是在我的笔记本上进行的,我的笔记本的CPU类型为:
model name : Intel(R) Core(TM)2 Duo CPU T7250 @ 2.00GHz
cpu MHz : 800.000
cache size : 2048 KB |
|