我遇到了mysql查询的问题。查询运行但有时它会使php超过最大内存。我喜欢80或90.000行坐标,有发动机转速和其他东西。我必须创建KML文件来单独显示路由。在发动机转速不为零的情况下,汽车正在移动,如果是,则汽车停止。表格的一半发动机速度包含0。当我遍历记录时,我也会在创建routes数组后同时删除记录,但它运行速度非常慢,有时会耗尽内存。可能是因为数据库中的数据量很大而且数据量很大或我的代码中存在一些逻辑错误?这是代码:
public function getPositions($device_id) {
$db = connect_database(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, DB_PORT);
$sql = "SELECT * FROM coordinates_log WHERE imei=:imei ORDER BY device_time ASC";
$statement = $db->prepare($sql);
$statement->execute(array(':imei' => $device_id));
$positions = array();
$delete_sql = "DELETE FROM coordinates_log WHERE id=:id";
$delete_statement = $db->prepare($delete_sql);
$counter = 0;
$flag = 0;
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
//here I flag the last started route
if ($row['vehicle_engine_speed'] <= 0) {
$flag = $counter;
}
$positions[] = $row;
$counter++;
}
if (!empty($positions)) {
$last_key = count($positions)-1;
//here I check if the route is completed yet, or he is on his way
if ($positions[$last_key]['vehicle_engine_speed'] != 0) {
for($i = $flag; $i<=$last_key; $i++){
unset($positions[$i]);
}
}
foreach ($positions as $position) {
$delete_statement->execute(array(':id' => $position['id']));
}
return $positions;
} else {
return FALSE;
}
}
答案 0 :(得分:1)
PHP中的PDO子系统提供两种查询:缓冲和非缓冲。如果您没有专门请求无缓冲的查询,则可以获得缓冲查询。缓冲查询在PHP引擎中消耗更多RAM,因为PDO将整个结果集提取到RAM中,然后在使用$statement->fetch()
时将其返回给您的程序。
因此,如果您的结果集非常大并且您可以一次处理它们,那么您将使用较少的RAM和无缓冲模式。您处理每一行,然后获取下一行,而不是尝试将它们全部保存在RAM中。
这是关于无缓冲模式的写法。
http://php.net/manual/en/mysqlinfo.concepts.buffering.php
缓冲模式通常更容易用于程序员,因为PDO从每个查询读取整个结果集并隐式关闭语句对象。这使得您的连接可用于下一个sql语句,即使您尚未处理结果集中的所有信息。在非缓冲模式下,如果要在处理结果集时运行其他mysql语句,则需要另外一个数据库连接来执行此操作。
您应该为SELECT * FROM coordinates...
结果集尝试无缓冲模式。
专业提示:如果您避开SELECT *
而使用SELECT col, col, col
,则可能会减少查询的开销,尤其是在您实际上并不需要所有列的情况下。
答案 1 :(得分:0)
关于“查看我的代码并告诉我它有什么问题”的问题在这里是不合适的。这不仅是因为代码是由计算机运行,而不是由人类阅读,而是因为代码本身很少与问题相关。
在此问问题之前,您必须分析代码,确定最慢的部分以及内存消耗。
我可以做出一些猜测,虽然我讨厌它。
select *
问题,从而为您的结果数组增加大量垃圾数据负担但是猜测并不是一个好的答案。你必须先解决你的问题。