香椿丛林: |
昨天下载了一个全国地名数据库,解压得到的.sql文件的文件大小达到200MB,即下图的position.sql。
总共有138万多行的语句,其中大部分都是insert语句,每个insert语句插入一行数据。导入SQLyog中运行后,发现迟迟没有结束。无奈只好让电脑继续运行,我先睡觉去了。今天醒来一看,我的乖乖,用了4个多小时!
我认为,每个SQL语句都是有固定开销的,比如使用select语句时,就算再简单的语句,需要的时间也是毫秒级,但是当获取的数据变大时,需要的时间并没有显著增加。这次执行这个SQL文件用了这么长时间,肯定是因为语句太多了,很多时间都花在了固定开销上。于是我觉得应该在执行SQL文件前对这个文件作一些处理,合并掉那些重复的insert,让一个insert插入多条数据,这样应该能让执行的时间缩短一点。 合并的方法并不难,比如下面这3个SQL语句:
只要把末尾的分号去掉,把后面的insert语句的values和之前的内容去掉,加个分号接起来就行了,像这样:
那么应该合并到多长呢?考虑到很多文本编辑器允许的最大行长度是65536,那么就用65536吧。写好程序后一运行,哇,200MB的文件,读取+处理+写入硬盘,居然只用了1.7秒不到!
这么长的文本的处理,我以为会花很长时间的,没想到会这么快! 好了,既然已经处理好SQL语句了,那么就运行看看吧。新建了一个数据库address,导入SQLyog,一切正常,行的长度并没有超标,心想“可以可以”。然后开始执行。在程序运行十几秒后,我觉得这一时半会的估计也没法结束,要不先买个菜去?正在准备的时候,SQLyog的“信息”窗口跳出了时间信息。嗯?怎么情况?我赶紧使用Ctrl+end跳到末尾看看,发现SQL文件末尾的id已经显示在上面了。难道已经好了?我不大相信,又打开idea,count一下行数看看,发现确实是执行完了。卧槽,卧槽,我忍不住直呼,怎么会那么快,1分02秒!
简直是不敢相信。之前的SQL文件需要4个多小时才执行完,这次只要1分钟!我又细看了一下每个语句的运行时间,发现确实如我想的,实际插入的实际其实很短,很多大部分时间都花在了固定开销上。
如上,实际插入了1200多行语句,但是时间只比原来插入1条语句的时候多1倍!这效率真是太恐怖了!完了我一边感叹一边买菜去了。买菜的时候我一边想,如果每一行的内容再增加会怎样?我网上查了一下,MySQL中可以在配置文件中设置一个参数max_allowed_packet,设定每行允许接收的内容的大小,默认值是1024KB。我心想我只设了65536,也就是64KB,那么是绰绰有余的。于是我将容量改成1024KB后再运行了一下,发现SQL文件比原来的小了一点点。导入SQLyog后,居然还能正常显示!厉害了我的SQLyog!然后执行。然而这次似乎没有那么顺利,执行开始后,我发现时间显示不大正常,估计最后的总时间会少很多。于是赶紧掏出手机进行计时,这时大约10秒已经过去了。当手机计时到37秒时,SQLyog停了。我看了看执行记录,果然没能正常执行,出错了。但是看起来速度应该也不会再有显著提高了,我想就这样吧。今后对数据进行备份后的再恢复时,可以想这样预先处理一下,这样速度真的是快太多了。更深层次的内容,我现在应该没有必要考虑(即便考虑了也暂时用不到)。 以下为SQL文件处理程序的源代码,逻辑很简单,只对insert语句进行合并。为保险起见,对表名进行了判断,如果表名不相符,那么肯定不能合并。但是数据库dump出来的SQL应该也不会出现这种情况。这里唯一需要注意的就是,我没有对一行里包含多个SQL语句的情况进行判断,也没有对一个insert语句是否插入了多个记录作判断。默认的情况就是一行一条insert语句,一个insert语句插入一条记录。(如果一个insert已经插入多条记录了,那么也不大需要我这个程序了)
|
主 楼 发布于:2017-11-19 22:04:42 编辑于:2017-11-19 22:11:42回复 |
香椿丛林: |
有个要注意的地方,就是writer最后要调用一下flush,否则文件最末尾的部分可能不会被输出到文件中,导致SQL语句出错。 |
2 楼 发布于:2017-11-19 22:20:45 回复 |
香椿丛林: |
还有个要注意的地方就是在打印builder对象时,builder的长度可能很长,在调用builder.toString()时,不要使用“+”号加上语句末尾的分号“;”,因为string的加号是重载过的,这样调用,会生成另外一个string对象,这在builder长度很长时可能会严重影响效率。应该将对builder的输出和分号的输出单独开来。 |
3 楼 发布于:2017-11-19 22:24:15 回复 |
香椿丛林: |
至于最后reader、writer的关闭,无所谓了,反正运行完了之后就退出了。 |
4 楼 发布于:2017-11-19 22:25:41 回复 |
还林退耕: |
一等男人无牵挂,二等男人打电话,三等男人跑上又跑下,四等男人坐在家里骂。 |
5 楼 发布于:2017-12-13 01:15:51 回复 |
酒爷2010: |
屌丝孤独一世,只有左手伴我一生 |
6 楼 发布于:2018-01-03 06:23:35 回复 |
软件2: |
你给我一份爱,我还你一夜情! |
7 楼 发布于:2018-01-20 07:10:02 回复 |
赛西施: |
好朋友像内裤就算你有大起大落他也包含着你,更好的朋友像避孕套永远为你的安全着想,最好的朋友像伟哥总是给予你支持! |
8 楼 发布于:2018-01-24 14:49:30 回复 |
绍峰: |
愚人术:把夹心饼拆封,小心地拨开两片饼干,去掉原来的夹心,拿出牙膏挤出适量至饼中,然后将之放至明显处,自然而然就有人光顾品尝了。 |
9 楼 发布于:2018-02-05 15:00:36 回复 |
暗室逢灯iuf: |
有缘相遇,无缘相聚;天涯海角,但愿相忆;有幸相知,无幸相守;沧海月明,天长地久。 |
10 楼 发布于:2018-02-11 05:25:10 回复 |
莫洛地: |
喜欢是淡淡的爱;爱是深深的喜欢! |
11 楼 发布于:2018-03-01 21:44:50 回复 |
小明神奇: |
新三从四德:太太出门要跟从,太太命令要服从,太太错了要盲从;太太化妆要等得,太太生日要记得,太太花钱要舍得,太太打骂要忍得。 |
12 楼 发布于:2018-03-25 14:56:55 回复 |
明天我要嫁给谁: |
楼主你知道的太多了。 |
13 楼 发布于:2018-04-22 15:34:15 回复 |
我不能输r: |
背叛是男人的血统,博爱是男人的宣言,自由是男人的口头禅,见异思迁是男人的风尚。 |
14 楼 发布于:2018-06-06 15:19:36 回复 |
艾丝帆: |
从你呱呱坠地时,上天就注定你是属于我的,虽然这个特别的日子不能和你在一起,但我们会一起庆祝你的60大寿 |
15 楼 发布于:2018-08-22 21:03:10 回复 |
左手泪遗弃: |
黑夜给了我一双黑色的眼睛,可我却用它来翻白眼。 |
16 楼 发布于:2018-09-13 16:39:10 回复 |
专研牌技手法: |
小王八,大乌龟,二狗子,笨笨驴,蠢货猪…………你真地是好涵养,这么骂你还能坚持看完短信! |
17 楼 发布于:2018-10-27 15:03:01 回复 |
小暗礁: |
小布什给拉登打电话:“你为什么要袭击美国?先给我一个理由”“需要吗?”“不需要吗?”“别那么认真,大家只是研究一下嘛!” |
18 楼 发布于:2018-11-08 16:07:16 回复 |
深埋买卖: |
笑摸二楼狗头 |
19 楼 发布于:2018-12-18 21:08:37 回复 |
龙虎战霸: |
我以为我颓废,原来我报废了! |
20 楼 发布于:2019-02-27 21:14:58 回复 |