前言:本例我们的需求是写一个每天0点运行的脚本。这个脚本从一个实时更新的数据库中提取数据。
每天跑一个Excel表出来,表里是当天零点与昨天零点时的差异的数据展示。
其实是很简单的需求,遇到的关键问题是数据量。该例的数据量太大,每次都能从数据库中拿出20多万条数据。
数据量大的话遇到的问题有这么几个:
1. 数据无法装入Excel表,因为使用Python处理Excel数据,最多插入65536行数据,多了就会报错;
2. 遍历筛选问题。我们拿到两天的数据进行对比,然后生成一个差异对比表。就需要遍历对比两张表的数据,数据量太大,遍历所用时间过长。
对这两个关键的问题,我们现作阐述。
【问题一:Excel表改为Csv表】
我们发现,Csv格式的表,是没有行数限制的,我们可以把20多万条数据直接插入csv表中。
【问题二:DICT类型数据的遍历】
按我们以往的经验,生成对比信息的字典代码如下:
defgetCurrentCompareMessageDict0(dict0,dict1):
'''未被优化的获取当前对比信息字典'''dlist0=list(dict0.keys())
dlist1=list(dict1.keys())
dict2={}
fori inrange(len(dlist1)):
ifdlist1[i] not indlist0:
key=dlist1[i]
value=[0,dict1[dlist1[i]]]
dict2[key]=value
else:
ifdict1[dlist1[i]]/100.0!= dict0[dlist1[i]]:
key=dlist1[i]
value=[dict0[dlist1[i]],dict1[dlist1[i]]]
dict2[key]=value
returndict2 即,先构建两个dict的key列表。
然后,以key列表的长度为上限,进行for循环,采用DICT[KEY]的方式来进行列表数据的筛选。
这个方法的运行是超级慢的。
经过研究我们将该方法改进如下:
defgetCurrentCompareMessageDict(dict0,dict1):
'''优化的获取当前对比信息字典'''dict2={}
i=0ford,x indict1.items():
ifdict0.has_key(str(d)):
ifx/100.0!= string.atof(dict0[str(d)]):
key=d
value=[string.atof(dict0[str(d)]),x]
dict2[key] = value
else:
key=d
value=[0,x]
dict2[key]=value
returndict2 采用该方法后,两组20多万条数据的比对筛选,在1秒内就完成了。
经测试,优化方法后速度提高了大约400倍!
这个方法优化了哪里呢&#