【发布时间】: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->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