MariaDB社区

标题: 批量插入疑惑 [打印本页]

作者: win1027    时间: 2012-6-20 15:52
标题: 批量插入疑惑
java代码里我有两个批量插入动作,连接池用的boncp,代码形式一样,如下:
            con = DbConnectionManager.getConnection();
            con.setAutoCommit(false);
            pstmt = con.prepareStatement(INSERT_RECMNDINFO);
            for (RecommendInfo recmndInfo : recmndInfos)
            {
                pstmt.setString(1, recmndInfo.getToJID());
                pstmt.setString(2, recmndInfo.getRecommendedJID());
                pstmt.setInt(3, recmndInfo.getStatus());
                pstmt.setString(4, recmndInfo.getCreateTime());
                pstmt.addBatch();
            }
            pstmt.executeBatch();
            con.commit();

但产生的二进制日志文件一个产生的形式如下:
INSERT INTO T_Phonebook (username,contactphone,contactName,createTime,countryCode) VALUES ('10100150002','13200999991','friend1','001340177104460','0086'),('10100150002','13200999992','friend2','001340177104460','0086')....(后面省略)
另一个产生二进制文件如下:
BEGIN
/*!*/;
# at 12108
#120620 15:28:47 server id 1  end_log_pos 12346         Query        thread_id=274        exec_time=0        error_code=0
SET TIMESTAMP=1340177327/*!*/;
INSERT INTO T_PendingRecommend(tojid,recommendedjid,status,createtime) values('10100999998@tanjianglong.hotalk.com','10100150002@t.hotalk.com',1,'001340177104461')
/*!*/;
# at 12346
#120620 15:28:47 server id 1  end_log_pos 12584         Query        thread_id=274        exec_time=0        error_code=0
SET TIMESTAMP=1340177327/*!*/;
INSERT INTO T_PendingRecommend(tojid,recommendedjid,status,createtime) values('10100150002@t.hotalk.com','10100999999@tanjianglong.hotalk.com',2,'001340177104461')
/*!*/;
# at 12584
#120620 15:28:47 server id 1  end_log_pos 12822         Query        thread_id=274        exec_time=0        error_code=0
SET TIMESTAMP=1340177327/*!*/;
INSERT INTO T_PendingRecommend(tojid,recommendedjid,status,createtime) values('10100999999@tanjianglong.hotalk.com','10100150002@t.hotalk.com',1,'001340177104461')
/*!*/;
.
.
.
.(省略中间的十几条)
# at 12822
#120620 15:28:47 server id 1  end_log_pos 12849         Xid = 25064835
COMMIT/*!*/;

为什么两种一样的批量插入方式产生的二进制文件不一致?后面这种拆成单条的执行语句怎么样才能让它变成一条执行语句?

作者: hm3030    时间: 2012-6-20 16:34
MySQL默认auto_commit=1,即执行一次就提交一次,则记次binary log,这应该是你第一种binary log形式。
但从代码con.setAutoCommit(false);,看出,你程序设置为0,即需要手动提交con.commit();
在没commit以前,你的任何DML操作都是在一个事物里,所以就有了你第二种binary log形式。

作者: win1027    时间: 2012-6-20 16:59
hm3030 发表于 2012-6-20 16:34
MySQL默认auto_commit=1,即执行一次就提交一次,则记次binary log,这应该是你第一种binary log形式。
但 ...

好像没明白我的意思哦,我意思是
第一种我批量插入了10条记录,二进制日志里面显示插入语句形式是:
insert into (..) values(..),(..),(..)...
说明帮我把十条插入语句拼接成一条插入语句(这就是我想要的结果,明显比第二种方式效率些)

第二种我也是批量插入了10条记录,二进制日志里面显示插入语句形式是:
insert into (..) values(..);
insert into (..) values(..)
insert into (..) values(..)
.
.
.
10条插入语句都是单独的,并没有拼接成一条。
我批量插入的语句两种方式都是一致的,没有什么不同之处,不明白什么造成了这种差异?

作者: hm3030    时间: 2012-6-20 17:09
对于为什么没拼接成一条,这需要你DBUG下自己的程序。
作者: beingman    时间: 2012-6-20 17:49
hm3030 发表于 2012-6-20 16:34
MySQL默认auto_commit=1,即执行一次就提交一次,则记次binary log,这应该是你第一种binary log形式。
但 ...

日志插入语句的不同形式跟自动提交设置没有关系吧。
作者: beingman    时间: 2012-6-20 17:55


感觉跟代码里的pstmt.addBatch()有关,这种扩展插入似乎是先用循环处理生成SQL语句,跟数据库的
交互只有一次;下面那个分立的插入似乎是在循环内进行每一次数据库插入操作。

作者: win1027    时间: 2012-6-20 19:54
找到原因了,mysql真正能批量更新需满足1.加参数rewriteBatchedStatements=true;2.jdbc版本号大于5.1.17。  我程序第二条没有满足,照成批量插入还是变成了每条请求。 更新驱动后就是真正的批量了
作者: beingman    时间: 2012-6-20 20:42





欢迎光临 MariaDB社区 (http://123.56.88.72/) Powered by Discuz! X3.2