我正在使用更新功能,我将大约40,000行插入到mysql数据库中。在制作该数组时,我出现内存不足错误(试图分配41个字节)。
最终的功能是这样的:
function Tright($area) {
foreach ($area as $a1=>&$a2) {
mysql_query('INSERT INTO 0_right SET section=\''.$a2['sec_id'].'\', user_id=\''.$a2['user_id'].'\', rank_id=\''.$a2['rank_id'].'\', menu_id=\''.$a2['menu_id'].'\', droit = 1;');
}
}
我有两个问题。这上面的工作负担对于php来说是否过于自然?
如果不是,有人可以建议我应该在哪里检查?如果是的话,是否有办法将$ area数组分解为子数组并执行该函数,也许这样我就不会遇到内存不足的问题。还有其他解决方法吗?
谢谢你们。
编辑:@halfdan,@ Patrick Fisher,你们两个人都谈到过制作单个多插入查询。在这个例子中,你是怎么做到的。
答案 0 :(得分:3)
首先,您应该将所有值组合成一个INSERT
语句,而不是40,000个不同的查询。
其次,是的,你内存不足是很自然的。您可以使用ini_set()
在运行时增加此限制,例如ini_set('memory_limit', '16M');
要一次插入多个值,您的SQL应如下所示:
INSERT INTO 0_right (section, user_id, rank_id, menu_id, droit) VALUES
(1,1,1,1,1),
(1,2,1,1,1),
(1,3,1,1,1)
您可以像这样构建查询:
$values = '';
foreach ($area as $a){
if ($values != ''){
$values .= ',';
}
$values .= "('{$a['sec_id']}', '{$a['user_id']}', '{$a['rank_id']}', '{$a['menu_id']}', 1)";
}
$sql = "INSERT INTO 0_right (section, user_id, rank_id, menu_id, droit) VALUES $values";
答案 1 :(得分:1)
这些都是解决问题的好方法。如果这是一次性脚本,只需增加RAM并确保脚本没有超时(php.ini文件中的max_execution_time),你应该没问题。
如果它是一个很大的插入语句,它可能运行得更快,但是你需要支付在PHP端构建大量查询的成本(因此内存不足问题仍将存在,并且会更糟糕的是字符串连接)。但老实说,谁在乎你是否只是在运行一次呢?
但是,如果您要一直执行此操作(例如在网页上),我建议采用其他方法......例如限制区域大小,剪切功能或以不同方式存储数据。 / p>
答案 2 :(得分:0)
PHP具有内置(可配置)内存限制,以防止单个脚本以错误的方式阻塞整个计算机。根据您的版本,该限制默认为8MB(5.2.0之前),16MB(5.2.0)或128MB(5.3.0)。
您可以通过ini_set或php.ini更改限制。