表
+-----------+--------------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+--------------+------+-----+-------------------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(32) | NO | | NULL | | | pid | varchar(32) | NO | | NULL | | +-----------+--------------+------+-----+-------------------+----------------+
步骤:测试
begin
set @i=0;
while @i<200 do
insert into test.table_test
(name, pid) values ('1', '1');
set @i=@i+1;
end while;
end
Run Code Online (Sandbox Code Playgroud)
跑:
mysql> call test();
Query OK, 0 rows affected (17.24 sec)
Run Code Online (Sandbox Code Playgroud)
但是当我用jdbc插入数据时,插入10 ^ 5行只需要大约9秒(如果我使用批量插入,插入10 ^ 5行只需要大约2.4秒).
java代码:
static String mySqlUrl="jdbc:mysql://127.0.0.1:3306/test?rewriteBatchedStatements=true";
static String sql = "insert into bael_test(name, pid) values(?, ?)";
public static void test_mysql_batch(int point){
Connection conn=getConn("mysql");
clear(conn);
try {
PreparedStatement prest = conn.prepareStatement(sql);
long a=System.currentTimeMillis();
for(int x = 1; x <= 100000; x++){
prest.setString(1, "name");
prest.setString(2, "pid");
prest.addBatch();
if(x%point==0){
prest.executeBatch();
conn.commit();
}
}
long b=System.currentTimeMillis();
print("MySql batch insert 10^5 rows",a,b,point);
} catch (Exception ex) {
ex.printStackTrace();
}finally{
close(conn);
}
}
Run Code Online (Sandbox Code Playgroud)
那么为什么MySQL插入比JDBC慢?
JDBC 代码正在执行扩展插入。
(我们在这里没有看到实际的 SQL 语句,也没有看到 SQL 文本中第一个位置参数的绑定,只有第二个和第三个参数。我将做出一个假设(可能是错误的) JDBC 为未绑定参数提供 NULL 值。)
因此,从 JDBC 驱动程序发送到 MySQL 的实际 SQL 语句的形式如下:
INSERT INTO test.table_test (id,name, pid) VALUES (NULL,'name','pid')
,(NULL,'name','pid')
,(NULL,'name','pid')
,(NULL,'name','pid')
,...
Run Code Online (Sandbox Code Playgroud)
然而,在您的 MySQL 过程中,您正在执行单独的语句:
INSERT INTO test.table_test (id,name,pid) VALUES (NULL,'name','pid');
INSERT INTO test.table_test (id,name,pid) VALUES (NULL,'name','pid');
INSERT INTO test.table_test (id,name,pid) VALUES (NULL,'name','pid');
INSERT INTO test.table_test (id,name,pid) VALUES (NULL,'name','pid');
Run Code Online (Sandbox Code Playgroud)
扩展插入形式将比单独的插入语句更有效。(MySQL 为每个语句执行执行大量繁重的工作。)
为了从 MySQL 过程中获得更好的性能,您需要执行以下操作:
BEGIN
SET @sqltext= 'insert into test.table_test (name,pid) values (''1'',''1'')';
SET @i=1;
WHILE @i<200 DO
SET @sqltext = CONCAT(@sqltext,',(''1'', ''1'')');
SET @i=@i+1;
END WHILE;
PREPARE stmt FROM @sqltext;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
Run Code Online (Sandbox Code Playgroud)
为了从 JDBC 中获得同样的性能下降,您需要执行单独的 INSERT 语句。
这是造成您所看到的巨大性能差异的最大因素。
这并不是说这是唯一的区别,但这可以解释您在执行过程时看到的 17 秒运行时间的大部分情况。使用单个扩展插入件的过程可能比运行 200 个单独的插入件快 100 倍。
您仍然存在性能差异,但至少这样您就更接近于将苹果与苹果进行比较。