mySQLi 插入脚本永远占用

Posted

技术标签:

【中文标题】mySQLi 插入脚本永远占用【英文标题】:mySQLi inserts script taking forever 【发布时间】:2014-01-08 19:26:47 【问题描述】:

这基本上是存储在我的 PHP 脚本中的内容

$query = $db->query("
SELECT *
FROM `media`
WHERE `id` > '$last_id'
AND `accounts_used` != ''
ORDER BY `id` ASC
LIMIT 100
");

foreach($query['results'] as $row) 
    $last_id = $row['id'];
    $accounts_used = explode(", ",$row['accounts_used']);
    $db->connect();
    foreach($accounts_used as $liked_account) 
        $account_id = str_replace(" ","",$liked_account);
        $media_id = $row['id'];
        $insert_array = array(
            "account_id" => $account_id,
            "media_id" => $media_id,
            "timesent" => "0000-00-00 00:00:00"
        );
        $db->insert("media_likes", $insert_array);
    
    $db->disconnect();

$row['accounts_used'] 的一个例子是这样的

61519, 65894, 63561, 61718, 63567, 66924, 66979, 66972, 66637, 66295, 66842, 64775, 51898, 64631, 65044, 67226, 67582, 66861, 51543, 61564, 65597, 66863

平均而言,accounts_used 行包含大约 1000/2000 个以逗号分隔的唯一 ID,我想根据逗号展开并将每个 ID 插入到另一个表中。

media_id 包含一个大约 5 位长的整数值,account_id 大致相同

这个脚本大约需要 3 分钟才能完成,有什么具体方法可以改进这些功能吗?还是更快的方法?

【问题讨论】:

"用逗号分隔的唯一 ID,"arggggg 规范化! 如果你要插入很多行,你想使用一个事务。发生的事情是在每次插入之后,它需要更新索引。在事务中,它只会在提交后才这样做。这应该会加快速度。 SELECT * 是真正的数据库杀手。 使用mysqli 时,您应该使用参数化查询和bind_param 将用户数据添加到您的查询中。 避免使用字符串插值来完成此操作。 【参考方案1】:

我可以看到一些可能会有所帮助的事情:

1 - 您在处理每一行数据后打开和关闭数据库连接(不要)

2 - 您可以使用准备好的语句让 mysql 连接“预编译”您的插入语句

3 - 围绕插入使用事务,这样您的索引只会更新一次

【讨论】:

非常感谢,现在只需 6 秒即可完成使用事务并将我的连接/断开连接置于 foreach 循环之外【参考方案2】:

您可能有一个包含很多行的表,因此问题不在于您插入自身的方式,而在于表的优化。 如果是这种情况,您可以尝试更改索引和外键,这可能会提高速度。 您也可以尝试内联插入,看看它是否有所改善。

【讨论】:

以上是关于mySQLi 插入脚本永远占用的主要内容,如果未能解决你的问题,请参考以下文章

Linux查看占用swap的进程脚本

PHP mysqli_free_result()与mysqli_fetch_array()函数

扫描端口占用情况的python脚本

swap分区占用情况脚本

如何查看mysql内存占用原因

看端口是否被占用的python脚本