楼主跳槽新入职了一家专门做国内某巨头通信业务的软件公司。既然是巨头,又是做通信的,那数据量必然很大的,对吧。这个没问题。害,关键是楼主以前写代码没接触过这么大数据量的,最大的也就几万条,十来万条。十几万条写代码其实可以差不多一样,基本上不会遇到什么要优化,要注意内容溢出的问题。但是上了百万级的话,那是完全不行的,因为需要查询效率,内存溢出,插入效率等等问题。 于是乎,就有了这篇文章。写出来记录一下。
数据量大小
: 380+w.
涉及表
:7-8张好像,具体没统计.
需求场景
:因为客户,要去O(oracle),全面转mysql,但是mysql公司内部规定不允许使用存储过程和函数(因为一个存储过程或函数,写起来可能是成百上千行的sql,如果你不在的话,那后期维护,修改将是灾难性的)。所以给我的需求就是,将oracle的存储过程转到mysql上,但是又不能直接在mysql上改为mysql的存储过程和函数,这时候只能用代码了,然后就有了下面的故事了。
因为之前没接触到大数据量,和也没考虑过磁盘io问题(确实够菜的)。然后是新来的吗,所以就想表现表现,加班加点直接全表查询。查询插入,修改,还没在大数据表加索引的那种,有些还需要循环比对插入循环插入…。这个时候代码逻辑没问题.
上面的操作出现的问题
:
第一个问题:查询慢。
第二个问题:内存溢出。
解决方案
:
第一个问题:查询慢这个先不解决。
第二个问题:内存溢出,好吧。为自己的菜背锅,主要是没遇到过这种场景而导致的问题。然后就优化,以前在公众号看到过不少例子,所以就想起来,分页查询嘛。
解释一下,这里还可以用时间来做条件帅选查询的,效率更好,但是奈何这里的时间格式有好几种,,,,
到这里这些问题算是优化完,能正常跑了
。
说明一下这里的这个需求其实是完成了的 但是太慢了,,,, 没24小时完不成,,,,,
。
由于是查询插入也就是说查询完直接把所有结果集都插入进去。数据量少的话 能这么干的。但是我们这有300多w数据…完犊子了 又遇到问题了… 真难受,,这时候心里就想 完犊子了。
面试的时候我牛皮吹老大了,面试官有问我处理过数据量大的情况吗? 我说有,处理过千万级数据的查询和插入。面试官也没深问,就这么过去了,如今IG没想到还真有这场景,,,, 害 没办法想办法解决吧
。
上面遇到的问题是,查询出来的是全表然后将查询出来的结果全部录入。也就是如下图这样:
这样大批量数据的时候会很慢,很慢。
找到问题就好了,那我们能不能把他们变成小批量呢?哈哈 可以的。
就是把查询的语句拿出来,查出来的数据做一个集合对象 然后每次从集合对象里面取5000条出来,批量执行这不就解决了吗?对吧 哈哈
我的做法就是这样,把查询和录入分开,查询出来存一个集合,然后分割集合,然后批量录入:
这样。
开始优化查询的sql
:
查询很慢,无非就是建立正确的索引嘛。
首先把sql在navicat上解释跑一下。然后根据情况建立索引。 尽量就是把type 优化到ref,这样简直无敌快。
首先就是 查询条件尽量用联合索引覆盖,连表查询 小表连大表。这样子 然后再去看type,是否用到索引,索引是否正确被应用。
最后我把这个东西 本来要24小时+的 硬是优化到了只要30多分钟就能执行完,,,,
也算是从一个“小白”晋级了,在这个问题上将之前学到的东西都应用上了,学到了不少东西。
唉,这个过程是真的挺煎熬的,挺难的吧,因为就是这个存储过程语句还是挺长的,有很多地方需要优化,优化完之后再测试,再优化,再测试… 不过完成之后,还是挺值的。
放弃不难,但坚持一定很酷。
感谢大家观看。加油。打工人。内容有点粗糙,后续再补充!