我正在使用while循环从mysql中提取记录。这是为了重置一个意外抬起的日志,所以我通过从DB的备份中提取ID和时间戳并使用这些值更新生产表来修复以前的记录。
我希望限制内存使用,并认为此解决方案使用的更少,因为此日志表中有12,545,628条记录。只需快速拉出1GB内存中的ID和时间戳字段。
这是一次将内存使用量限制为一条记录,还是使用相同的直接拉动所有ID和时间戳并预测那些?
(我已经设置了一个数据库类,因此PDO可能看起来很奇怪)
$sql = 'SELECT id, timestamp FROM log_people WHERE 1';
$Test->sqlQuery($sql);
while ($testdb = $Test->sth->fetch(PDO::FETCH_ASSOC)) {
$Prod->beginTransaction();
try {
$sql2 = 'UPDATE log_people SET timestamp = "'.$testdb['timestamp'].'" WHERE id = '.$testdb['id'];
$Prod->sqlQuery($sql2);
} catch (exception $err) {
$Prod->rollback();
echo $err->getMessage();
}
}
我是否应该执行以下代码,一次只能拉动和修改一条记录?
while ($count < 12545628){
$sql = 'SELECT id, timestamp FROM log_people WHERE id ='.$count;
$Test->sqlQuery($sql);
$testdb = $Test->sth->fetch(PDO::FETCH_ASSOC)
$Prod->beginTransaction();
try {
$sql2 = 'UPDATE log_people SET timestamp = "'.$testdb['timestamp'].'" WHERE id = '.$testdb['id'];
$Prod->sqlQuery($sql2);
$count++;
} catch (exception $err) {
$Prod->rollback();
//return $err->getMessage();
echo $err->getMessage();
}
}
答案 0 :(得分:0)
在您的问题中,您使用相同的先前值更新表。在内存方面,php的内存限制可以在php.ini或php代码中定义。并且你的第二个代码与第一个代码相比具有内存效率,但由于每个id的分开查询,因此非常耗时。
答案 1 :(得分:0)
我也不明白为什么在更新这些记录时需要选择所有记录。
无论如何,有一些提示可以帮助你处理内存使用。
第一点有一个函数可以告诉你脚本内存不足的地方你可以查看它使用此功能memory_get_peak_usage();
第二点您还可以将null重新分配给vars并取消设置。当垃圾收集器正在进行轮次时,unset();
函数很有用,但在此之前,unset();函数只是破坏对数据的变量引用,数据仍然存在于内存中,并且PHP将内存视为正在使用,尽管不再有指向它的指针。解决方案:为变量分配null以清除数据,至少在垃圾收集器获取它之前。
$ var = null;
你也可以使用unset();取消设置变量指针,但据我所知,内存使用量差别不大:
unset($var);
第三点另一种方法是通过在处理对象时破坏对象引用来做到这一点。
protected function __distruct()
{
$this->childObject = null;
}