【问题标题】:Out of memory error with multiple inserts多次插入时出现内存不足错误
【发布时间】:2014-03-02 23:21:49
【问题描述】:

我有一个脚本,它从用户那里获取可变数量的输入并将它们插入到数据库表中,每个项目一行。对于小型数据集,这可以正常工作,但对于较大的数据集(超过 10 个项目),脚本总是会因内存不足错误而失败。这是我正在使用的代码 - 是否有更高效的内存方式来执行此操作?

$data = $_POST['dataArray'];
for ($i = 0; i < count($data); $i++)
{
    $mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
    $stmt = $mysqli -> prepare('INSERT INTO items(name, serial, cost) VALUES (?, ?, ?)');
    $stmt -> bind_param('sii', $data[$i]['name'], $data[$i]['serial'], $data[$i]['cost']);
    $stmt -> execute();
    $stmt -> close();
    $mysqli -> close();
}

FWIW,有问题的数据库表只有 4 列:

  • id [int(11), autoincrement]
  • 名称[varchar(256]
  • 串行[int(11)]
  • 成本[int(11)];

【问题讨论】:

  • 移动您的 SQL 连接并准备退出 for 循环,对于您的 close 语句也是如此,只保留 bind_param 和 execute 内部。您还可以将您的 bind_param 恢复为:$stmt-&gt;bind_param('sii', $data[$i]);,但在此之前,请确保类型的数组顺序相同。此外,您的成本字段应为 double(7,2),如果您计划使用诸如 100.23 之类的十进制值,则将持有数百万美元
  • 您是否有理由在您插入的每一行上打开和关闭一个新连接?
  • 如果你想要真正的效率,而不是单独插入每一行,你应该一次插入它们。 “插入项目(名称,序列,成本)值(a,b,c),(d,e,f)......;” stackoverflow.com/questions/14860606/… 是动态预准备语句的示例。
  • 感谢 Dan Farrell,您的回答最终对我有用。我之前曾尝试将连接打开和关闭移动到循环之外,但我仍然遇到同样的内存不足错误。我已将它们移到内部,希望立即创建/拆除连接和准备好的语句会更快地回收内存,尽管我现在意识到情况并非如此。

标签: php mysql sql memory mysqli


【解决方案1】:

您的问题是通过将它们包含在循环中来创建大量连接;修复使用这个:

$data = $_POST['dataArray'];
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$stmt = $mysqli -> prepare('INSERT INTO items(name, serial, cost) VALUES (?, ?, ?)');
for ($i = 0; i < count($data); $i++) {
    $stmt -> bind_param('sii', $data[$i]['name'], $data[$i]['serial'], $data[$i]['cost']);
    $stmt -> execute();
}
$stmt -> close();
$mysqli -> close();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 2018-04-17
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多