MySQL大批量数据插入,PHP之for不断插入时出现缓慢的解决方案及优化(转载)

公司有一个项目,需要频繁的插入数据到MySQL数据库中,设计目标要求能支持平均每秒插入1000条数据以上。目前功能已经实现,不过一做压力测试,发现数据库成为瓶颈,每秒仅能插入100多条数据,远远达不到设计目标。

到MySQL官方网站查了查资料,发现MySQL支持在一条INSERT语句中插入多条记录,格式如下: 
INSERT table_name (column1, column2, ..., columnN) 
VALUES (rec1_val1, rec1_val2, ..., rec1_valN), 
(rec2_val1, rec2_val2, ..., rec2_valN), 
... ... 
(recM_val1, recM_val2, ..., recM_valN);

按MySQL官方网站,用这种方法一次插入多条数据,速度比一条一条插入要快很多。在一台开发用的笔记本电脑上做了个测试,果然速度惊人。

测试环境:DELL Latitude D630, CPU T7250 @ 2.00GHz, 内存 2G。Windows XP Pro中文版SP2,MySQL 5.0 for Windows。

MySQL是新安装的,建立了一个名为test的数据库,在test数据库建了一个t_integer表,共两个字段:test_id和test_value,两个字段都是INTEGER类型,其中test_id是Primary Key。

准备了两个SQL脚本文件(写了个小程序生成的),内容分别如下:

-- test1.sql 
TRUNCATE TABLE t_integer; 
INSERT t_integer (test_id, test_value) 
VALUES (1, 1234), 
(2, 1234), 
(3, 1234), 
(4, 1234), 
(5, 1234), 
(6, 1234), 
... ... 
(9997, 1234), 
(9998, 1234), 
(9999, 1234), 
(10000, 1234); 
-- test2.sql 
TRUNCATE TABLE t_integer; 
INSERT t_integer (test_id, test_value) VALUES (1, 1234); 
INSERT t_integer (test_id, test_value) VALUES (2, 1234); 
INSERT t_integer (test_id, test_value) VALUES (3, 1234); 
INSERT t_integer (test_id, test_value) VALUES (4, 1234); 
INSERT t_integer (test_id, test_value) VALUES (5, 1234); 
INSERT t_integer (test_id, test_value) VALUES (6, 1234); 
... ... 
INSERT t_integer (test_id, test_value) VALUES (9997, 1234); 
INSERT t_integer (test_id, test_value) VALUES (9998, 1234); 
INSERT t_integer (test_id, test_value) VALUES (9999, 1234); 
INSERT t_integer (test_id, test_value) VALUES (10000, 1234);

以上两个脚本通过mysql命令行运行,分别耗时0.44秒和136.14秒,相差达300倍。

基于这个思路,只要将需插入的数据进行合并处理,应该可以轻松达到每秒1000条的设计要求了。

补充:以上的测试都是在InnoDB表引擎基础上进行的,而且是AUTOCOMMIT=1,对比下来速度差异非常显著。之后我将t_integer表引擎设置为MyISAM进行测试,test1.sql执行时间为0.11秒,test2.sql为1.64秒。

补充2:以上的测试均为单机测试,之后做了跨机器的测试,测试客户端(运行脚本的机器)和服务器是不同机器,服务器是另一台笔记本,比单机测试时配置要好些。做跨机器的测试时,发现不管是InnoDB还是MyISAM,test1.sql速度都在0.4秒左右,而test2.sql在InnoDB时且AUTOCOMMIT=1时要80多秒,而设置为MyISAM时也要20多秒。

方法一:用PHP构造一次插入多条,并多次以for插入,像装车一样,一车一车的把sql运过去。

<?php
for($i=0;$i<10;$i++){
mysql_query("insert into table_name (name,age) values (‘name1‘,‘age1‘),(‘name2‘,‘age2‘); //一车:i=1,第二车:i=2
}
?>

方法二:如果是网络和循环太慢,则建议用C来做这个事情,会提高三倍左右的速度,相对PHP可能会有相当的提升。 
方法三:用队列来做,分多个进程实现,可能有一定程序的时间上提高,同时要注意binlog的影响及索引的影响。BY:Jack

引自:http://www.tuicool.com/articles/zQV7zi

博客声明:

  本博客中的所有文章,除标题中注明“转载”字样外,其余所有文章均为本人原创或在查阅资料后总结完成,引用非转载文章时请注明此声明。—— 博客园-pallee

时间: 2024-08-24 06:38:27

MySQL大批量数据插入,PHP之for不断插入时出现缓慢的解决方案及优化(转载)的相关文章

MYSQL 大批量数据插入

最近在做MYSQL大批量数据的测试,就简单总结一下遇到的问题: 首先我是简单的写了一个MYSQL的循环插入数据的SP,具体如下: 这是插入100W数据的过程和结果,可以看到是换了55min +20S约3320秒(约300rows/s),看到之后我是只崩溃,就在网上查了些提速的方法: 0. 最快的当然是直接 copy 数据库表的数据文件(版本和平台最好要相同或相似): 1. 设置 innodb_flush_log_at_trx_commit = 0 ,相对于 innodb_flush_log_at

MySQL大批量插入数据

MySQL大批量插入数据 1. 对于Myisam类型的表,可以通过以下方式快速的导入大量的数据. ALTER  TABLE  tblname  DISABLE  KEYS; loading  the  data ALTER  TABLE  tblname  ENABLE  KEYS; 这两个命令用来打开或者关闭Myisam表非唯一索引的更新.在导入大量的数据到一 个非空的Myisam表时,通过设置这两个命令,可以提高导入的效率.对于导入大量 数据到一个空的Myisam表,默认就是先导入数据然后才

mysql大批量插入数据的4种方法示例

前言 本文主要给大家介绍了关于mysql大批量插入数据的4种方法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 方法一:循环插入 这个也是最普通的方式,如果数据量不是很大,可以使用,但是每次都要消耗连接数据库的资源. 大致思维如下 (我这里写伪代码,具体编写可以结合自己的业务逻辑或者框架语法编写) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 for($i=1;$i<=100;$i++){  $sql = 'insert...............';  /

jdbc批量插入实现大批量数据快速插入

今天在做一个将excel数据导入数据库的程序时,由于数据量大,准备采用jdbc的批量插入.于是用了preparedStatement.addBatch();当加入1w条数据时,再执行插入操作,preparedStatement.executeBatch().我原以为这样会很快,结果插入65536条数据一共花30多分钟,完全出乎我的意料.于是问了一下同事,他们在处理这种大批量数据导入的时候是如何处理的,发现他们也是用的jdbc批量插入处理,但与我不同是:他们使用了con.setAutoCommit

java大批量数据导入(MySQL)

? 版权声明:本文为博主原创文章,转载请注明出处 最近同事碰到大批量数据导入问题,因此也关注了一下.大批量数据导入主要存在两点问题:内存溢出和导入速率慢. 内存溢出:将文件中的数据全部取出放在集合中,当数据过多时就出现Java内存溢出,此时可通过调大JVM的最大可用内存(Xmx)解决, 但终究不是王道.    MySQL支持一条SQL语句插入多条记录的操作,并且效率比单条插入快的不是一点点:但是MySQL一次可接受的数据包大小 也是有限制的,当一次插入过多时也可能造成数据包内存溢出,此时可通过调

php+mysql实现数据分批插入

上周需要将云端的数据有条件的录入到mysql中,最开始是使用遍历数据然后一条条的插入的笨方法,结果速度慢的要死,所以又随便写了个笨方法2.0,记录一下自己菜鸟的成长历程.同时这也是在博客园的第一篇文章,目的仅仅是单纯的记录一下自己的狗屎代码,因为我是菜鸟,哈哈... 比如说有10001条数据,每次插入1000条,分11次插入完成,代码如下: 1 <?php 2 /** 3 * Created by PhpStorm. 4 * User: Soup 5 * Date: 2016/12/29 6 *

解决 C++ 操作 MySQL 大量数据插入效率低下问题

往 Mysql 中,插入10000条简单数据,速度非常缓慢,居然要5分钟左右, 但是打开事务的话,一秒不到就搞定了 代码: #include <iostream> #include <winsock2.h> #include <string> #include "mysql.h" #pragma comment(lib, "libmysql.lib"); using namespace std; int main() { MYSQ

MySQL 大数据量快速插入方法和语句优化

MySQL大数据量快速插入方法和语句优化是本文我们主要要介绍的内容,接下来我们就来一一介绍,希望能够让您有所收获! INSERT语句的速度 插入一个记录需要的时间由下列因素组成,其中的数字表示大约比例: 连接:(3) 发送查询给服务器:(2) 分析查询:(2) 插入记录:(1x记录大小) 插入索引:(1x索引) 关闭:(1) 这不考虑打开表的初始开销,每个并发运行的查询打开. 表的大小以logN (B树)的速度减慢索引的插入. 加快插入的一些方法 如果同时从同一个客户端插入很多行,使用含多个VA

MySQL为数据表的指定字段插入数据

username not null 没有默认值/有默认值   insert不插入username字段 均不报错 2014年07月23日21:05    百科369 MySQL为数据表的指定字段插入数据 为数据表的指定字段插入数据,就是在INSERT语句中只向部分字段中插入值,而其它字段的值为数据表定义时的默认值. 基本的语法格式如下: INSERT INTO 表名(字段1,字段2,...,字段m) VALUES(值1,值2,...,值m); 字段1,字段2,...,字段m:表示数据表中的字段名称