在我的上一篇文章《Java与MySQL优化之旅(一)——从14小时到40秒》之中,我使一个用于往MySQL中插入数据的应用的运行时间从14小时下降到了不到40秒的时间。今日,我来看看还怎样把这个应用的运行时间缩短。
我首先分析了一下当前程序。当前的程序功能主要分为两部分:1、待插入词组的去重操作;2、批量往MySQL中插入词组(每次插入10000行)。对于第一部分,时间消耗约为10秒,对于第二部分时间消耗约为30秒,占去了总时间的四分之三。于是,很容易想到,我要提升程序的效率,应该先从第二部分入手尝试。
其实,第二部分消耗的时间,基本上都是被MySQL数据库消耗掉的。那么,如何提高MySQL的速度呢?
当前,程序操作的MySQL数据表采用的是InnoDB存储引擎。我们知道,在MySQL除了提供InnoDB存储引擎之外,还提供了一个MyISAM存储引擎,而且MyISAM在执行一些与事务关系不大的操作时其效率往往要远远高于InnoDB。对于当前程序使用的这个数据表来说,在往里面插入数据之前,他基本上就只是一张空表。而且在往其中插入数据到达过程当中,比不会有其他的线程对数据表执行查询等操作。因此,在执行程序之前首先把数据表使用的存储引擎转换成MyISAM将会是一个对性能十分有好处的行为。在命令行中执行以下命令:
- ALTER TABLE tablename ENGINE = MyISAM;
在完成了存储引擎的转换之后,重新执行程序,发现程序的运行时间下降到了15秒左右。再查看了一下输出的时间信息,发现程序消耗在插入数据上面的时间已经下降到了6秒左右。
至此,影响程序性能的部位从“数据库操作”转移到了“原始数据去重”上面了。那么,“数据去重”这部分应该如何提高速度呢?
注意到,在程序执行“数据去重”操作时,做了这么几步工作:
1、对无序数据进行排序(这里使用的是“快排”);
2、一次遍历有序数组,执行去重操作。
而在此之前,程序首先要把数据一次性装载进内存当中。
事实上,程序执行以上步骤的真正目的其实仅仅是要从已经装载进入内存当中的数据中去掉重复出现的数据而已。那么能否能够去掉程序当中“对无序数据排序”这么一步操作呢?
答案是肯定的。
JavaAPI当中为开发者提供了一个Hash