用于处理mysql中大量数据的最快查询

时间:2015-09-23 11:00:40

标签: php mysql pdo

我遇到了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;
        }
    }

2 个答案:

答案 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 *问题,从而为您的结果数组增加大量垃圾数据负担
  • 由于innodb设置,它可能是慢速写入。

但是猜测并不是一个好的答案。你必须先解决你的问题。

相关问题