优化插入数百万条记录,MySQL 和 PHP
Posted
技术标签:
【中文标题】优化插入数百万条记录,MySQL 和 PHP【英文标题】:Optimized insert in chuncks of millions of records, MySQL and PHP 【发布时间】:2012-05-16 01:10:25 【问题描述】:我需要用 php 函数生成的随机 SHA-1 哈希值填充 mysql 表。 我正在尝试通过将其拆分为 10000 个块来优化插入。 我的问题是: 以下方法有效吗?这是代码。
//MySQL server connection routines are above this point
if ($select_db)
$time_start = microtime(true);
//query
$query = 'INSERT INTO sha1_hash (sha1_hash) VALUES ';
for ($i=1; $i<1000001; $i++)
$query .= "('".sha1(genRandomString(8))."'),";
$count++;
if ($count ==10000)
//result
$result = mysql_query(rtrim($query,',')) or die ('Query error:'.mysql_error());
if ($result) mysql_free_result($result);
$count = 0;
$time_end = microtime(true);
echo '<br/>'. ($time_end - $time_start);
//function to generate random string
function genRandomString($length)
$charset='abcdefghijklmnopqrstuvwxyz0123456789';
$count = strlen($charset);
while ($length--)
$str .= $charset[mt_rand(0, $count-1)];
return $str;
编辑:$time_start
和 $time_end
变量仅用于性能测试目的。 MySQL表也只有两个字段:ID int(11) UNSIGNED NOT NULL AUTO_INCREMENT
和sha1_hash varchar(48) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
,引擎是MyISAM
EDIT2:计算机硬件的观点与问题无关。
【问题讨论】:
注意 MySQL 管理设置中允许的最大数据包大小:构建非常长的查询(正如数千次迭代所暗示的那样)可能会超过该限制。 在什么情况下有效?总执行时间?内存使用情况?系统负载? Wally,在所有提到的方面都很有效 确实,允许的最大数据包大小已增加到 1024 Mb,最低点 【参考方案1】:插入通常是大批量完成的,因为每次插入后都会更新索引。批处理允许您插入许多记录,然后只在末尾更新一次索引,而不是在每行之后。
但是,在自动递增主键索引的情况下,必须扩展索引才能添加新行,因此您不会在此处保存任何内容,因为您没有任何其他索引。
批处理还节省了解析查询和锁定的一些开销。不过,您也可以考虑使用参数化查询 (PDO)。
使用 PDO 的参数化查询一次插入一条记录也会非常快,因为 MySQL 只需解析一次查询,从那时起,它使用行数据的低开销二进制传输。
您可以在插入以LOCK TABLES
开始之前锁定表。这将节省一点表锁开销。
此外,由于 SHA1 始终是 40 个字符的十六进制编码 ASCII 值,您应该考虑使用 CHAR(40)
而不是 VARCHAR()
。这也会加快速度。此外,如果 SHA1 列被索引,请使用单字节字符集而不是 UTF8 来减小索引的大小并加快处理速度。
【讨论】:
确实,使用 char (40) 代替 varchar (48) 是一个很好的改进点,尤其是在拥有数百万条记录时。但是,输入字符串的长度可能会有所不同 - 它可以是 8 或 20,或 32 ......简而言之 - 冲突不是那么相关(或似是而非的 - 在 80 次操作中计算工作量少于 2 的冲突) 似乎将随机值插入哈希函数可能会导致冲突,但显然你是对的。如果你在 SHA1 中发现了冲突,你就会出名。以上是关于优化插入数百万条记录,MySQL 和 PHP的主要内容,如果未能解决你的问题,请参考以下文章
将数百万条记录从平面文件插入 SQL Server 的陷阱是啥?
如何使用 Talend Open Studio 处理数百万条 MongoDB 记录并将其插入 Postgres
将数百批 500k - 300 万条记录插入 PostgreSQL 数据库的最快方法