优化了数百万条记录、MySQL 和 PHP 的插入



我需要用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编辑2:计算机硬件的观点与问题无关。

插入通常是大批量完成的,因为索引在每次插入后都会更新。批处理允许您插入许多记录,然后仅在末尾而不是在每行之后更新索引一次。

但是,在自动递增主键索引的情况下,必须扩展索引才能添加新行,因此您不会在那里保存任何内容,因为您没有任何其他索引。

批处理还可以节省查询解析和锁定方面的一些开销。但是,您也可以考虑使用参数化查询 (PDO(。

使用

PDO 的参数化查询一次插入一条记录也会非常快,因为 MySQL 只需要解析查询一次,从那时起,它使用行数据的低开销二进制传输。

您可以在插入以 LOCK TABLES 开头之前锁定表。这将节省一点表锁定开销。

此外,由于 SHA1 始终是 40 个字符的十六进制编码 ASCII 值,因此应考虑使用 CHAR(40) 而不是 VARCHAR() 。这也将加快速度。此外,如果 SHA1 列已编制索引,请使用单字节字符集而不是 UTF8 来减小索引的大小并加快速度。

最新更新