场景:

最近正在做一个performance测试,在测试中,我必须准备大量的客户数据,以及与客户数据相关地合同数据,联系记录数据等。

客户数据为90万,合同数据达40万,联系记录数据达千万,还有一些跟踪数据达百万。

面对这样数量级的测试数据,相信大家跟我一样都会不约而同地想到使用sql语句来实现。

 

于是,在搞清楚数据关系之后,我开始动手写我的sql了。

为了使添加的数据更加接近真实的场景,我以客户作为起点,在添加客户后为此客户添加与之相关的合同数据,以及联系记录数据等。终于,经过连日的奋战(呵呵,可能开发人员只需要连小时地奋战),我终于把我的sql脚本写完了,并在上周五下班前kick start了脚本,大安旨意(翻译:本以为)可以在本周一看到数据生成完毕的我,却发现脚本居然还没有运行完,而且也才完成了目标的20%不到。

 

于是,开发人员就一同过来会诊我的脚本,发现症结如下:

1.使用太多的循环,且循环中嵌套循环;这样可以使数据关系非常清晰,但是其中使用的游标太多会严重减低数据插入的效率的。

   建议,如果游标>1000的话,就不要使用循环的方式了。

2.每insert一句就commit一次,降低了运行的效率

 

得到了症结,当然是出解决方案啦。

1.去掉循环,使用插入数据集(dataset)的方法。

   例如,有基础表TableA,其中有字段AA,AB,AC

            待插入数据的表TableB,需要插入字段BA,BB,BC,且BA是可以使用表A的字段AA作为数据集的。

此时我们可以使用一下语句:

***************************

insert into TableB (BA,BB,BC)

select AA,'1','0' from TableA

***************************

如果TableA数据是,

AA,AB,AC

1,A,A

2,B,B

3,C,C

那么执行完语句后,TableB的数据是

BA,BB,CC

1,1,0

2,1,0

3,1,0

 

2.在使用where语句时,进行使用自增长位作为查询条件

例如:在TableA中AA项为自增长项,这样数据库本身已经对它建有index。使用它作为查询条件就会比使用AB,AC项更加快。

还有,在为AA项限制条件时,不要使用like ‘%1’这些后匹配方式;尽量使用between ... and ...或者< >的匹配方式

 

3.如果无法去掉的循环,都要尽量减少循环中的游标,不要循环中嵌套循环

  例如,对于一些基础表,如TableA,需要添加90万的数据量。就只是使用一个游标进行循环插入,且循环中执行的语句也只是insert数据的语句,不要掺杂其他复杂的运算或者再嵌套循环

 

根据开发人员的建议,我重新修改了sql,将中间的循环去掉,尽量多地使用数据集的方式来插入数据。

sql生成数据的效率得到了飞速地提高,原先2天无法加完的数据,一个晚上就搞掂了。

 

效率是提高了,但是数据中的内容就会变得相对集中,例如有10几万的数据都是同一时刻,同一个操作用户生成的。这样的话,对于一些查询就非常不利了。因为有可能一次需要查询出几十万的数据,这样是也不符合现实情况。

于是,对于这种情况,我们需要针对不同的场景,对数据进行微调。例如使用循环,将数据的udpatetime,或者updateguy进行随机更新。

这样就又保证了数据量,也保证了数据的真实性。

posted on 2010-05-26 17:13  Carrie  阅读(600)  评论(2编辑  收藏  举报