优化插入数百万条记录,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_INCREMENTsha1_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

使用 hive sql 批量插入数百万条记录到 hive?

将数百批 500k - 300 万条记录插入 PostgreSQL 数据库的最快方法

Db2 for i - RUNSQLSTM - 插入包含数百万条记录的脚本

MySQL 最佳实践 —— 高效插入数据