本文共 1037 字,大约阅读时间需要 3 分钟。
手头有一个500多万条记录的csv文件,需要导入数据库。
一开始mysql表是默认innodb引擎的,表只有一个自增id主键,导入到大概十万左右的时候,速度缓慢到3-5条/每秒,所以这样肯定不行。当时查阅资料之后发现myisam表会比innodb的insert速度快,所以将表改成myisam引擎,速度挺快,但是到了十五万左右的时候速度又降下来了。
这个时候经过分析,发现瓶颈不是在insert,而是在select,我的逻辑是每次insert之前要根据orderid和productid来select查询一下表中是否已经有数据,如果没有再insert,瓶颈就是在select了。
到这里的时候,我决定把orderid和productid进行md5加密之后保存到redis中,然后之后只从redis中判断是否已存在,如果redis中没有的话,再去表中查询。这个方案上了之后,insert速度又提升了,直到到了120万条数据的时候,速度又慢下来了。
这个时候的数据都是新的,我从redis中检索的时候总是没有,所以还要去数据库中去select,这个时候数据库已经一百多万条数据,我分析了下每次查询都要消耗大概0.7秒,瓶颈就是在select查询这里,于是我决定给表添加index。
我决定给orderid和productid添加normal索引,索引有两种类型,hash和b-tree,因为hash在你是=查询条件的时候,可以一次定位,速度极快,因为我的select都是orderid=xxx and productid=xxx,所以决定使用hash索引。
上了索引之后,那个速度,就像飞一样了,现在已经到了300万了,一点没有慢下来的意思。insert速度在每秒5000左右。
所以我后悔啊,其实根本不需要额外使用redis来保存索引,mysql表自己的索引就很快。当然我在redis中保存索引是因为我的脚本总是挂,每次都要重新开始检索文件,所以也还有一定作用。
当然最后我才发现,csv文件可以直接导入mysql的。。。。。。瞬间感觉自己秀逗了。。。。。。
但是还好吧,如果不这么绕一圈,我也不会发现这么多问题,学到一些东西吧。
总结:
以后涉及到数据表的操作的,首先要考虑索引,另外如果要操作的数据量比较大,可以采用分库分表来操作,可以酌情分为20-100等等个表来倡导做。当然目前来看一个表数据到了几百万速度都没有多慢,所以如果要分库分表的话,估计是个天文数字才会用到。
转载地址:http://ghmyn.baihongyu.com/