标签:
工作中需要读取很多大数据量(1000w条)的文件并写入到mysql表里,涉及到的技术点主要是数据库的addbatch及水平分表。
数据库的写入场景包括:一条一条的写入和批量写入,这里数据库的批量增加使用mybatis框架完成。
水平分表的意思是本来我们要将1000w的数据写入到一张表里,但为了考虑未来表容量的扩展,及表的性能要求,将本来写入一张表转换成写入多张表。
我在这里没有使用一些框架(Cobar Client,Shardbatis,mybatis-shards),而是采用Hash分表来实现的。
说一下核心部分,整个工程参考我的github,运行的main方法在org/xiongmaotailang/mybatis/batchinsert/DbUtil.java中,涉及到的脚本是sql.txt
需要的数据表示例,包括4个字段。
CREATE TABLE `newspvuv` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `pv` bigint(11) DEFAULT NULL, `uv` bigint(11) DEFAULT NULL, `time` varchar(15) NOT NULL, PRIMARY KEY (`id`) )
接下来看看批处理的mapper.xml文件(工程中org\xiongmaotailang\mybatis\batchinsert\mappers\DataMapper.xml),批量插入方法的定义
<mapper namespace="org.xiongmaotailang.mybatis.batchinsert.mappers.DataMapper"> <insert id="insertPVUV"> insert into ${table}(pv,uv,time) values(#{pv},#{uv},#{time}) </insert> <insert id="batchInsertPVUV" parameterType="java.util.List"> insert into ${table}(pv,uv,time) values <foreach collection="list" item="item" index="index" separator=","> (#{item.pv,jdbcType=INTEGER},#{item.uv,jdbcType=INTEGER},#{item.time,jdbcType=CHAR} ) </foreach> </insert> </mapper>
id="insertPVUV"是一条一条的写入的配置、id="batchInsertPVUV"是批量写入的配置。
对上边二个配置的main方法在DbUtil中。
public static void main(String[] args) throws InterruptedException { testInsert(); testBatchInsert(); } private static void testInsert() { long start=System.currentTimeMillis(); for (int i = 0; i < 1000; i++) { addPvUv(12,i,"123"); } System.out.println("insert 1000 row :"+(System.currentTimeMillis()-start)+"ms"); } private static void testBatchInsert() { long start=System.currentTimeMillis(); List<NewsPvUv> list=new ArrayList<NewsPvUv>(); for (int i = 0; i < 1000; i++) { NewsPvUv n = new NewsPvUv(12, i, "123"); list.add(n); } addPvUv(list); System.out.println("batch insert 1000 row :"+(System.currentTimeMillis()-start)+"ms"); }
上边对比了对1000条数据的二种写入方式,在我笔记本的测试结果如下图,可见批量写入的性能高效。
标签:
原文地址:http://www.cnblogs.com/xiongmaotailang/p/5294795.html