600000 位用户的 GPS table

GPS table of 600000 users

我正在使用 mysql。我的编程语言是 php.

我有 600.000 个用户,我每 10 秒通过 cell-phone 的 gps 获得这些用户中的 latlon 一次。

我对此的一些疑问table:

我的一些查询需要 7-14 秒,例如:

SELECT m1.*
            FROM gps m1 LEFT JOIN gps m2
             ON (m1.driver_id = m2.driver_id AND m1.id < m2.id)
            WHERE m2.id IS NULL

我觉得这个table太大了。

为了这个 table 使用像 Cloud Bigtable 这样的第三方是个好主意吗? 有什么解决办法吗? 我们先讨论MySQL修复。

我的table:

CREATE TABLE `gps` (
  `id` int(11) NOT NULL,
  `driver_id` int(11) NOT NULL,
  `trucks_drivers_id` int(11) NOT NULL,
  `x` varchar(100) COLLATE utf8_persian_ci NOT NULL,
  `y` varchar(100) COLLATE utf8_persian_ci NOT NULL,
  `speed` varchar(100) COLLATE utf8_persian_ci NOT NULL,
  `time_stamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci;

我没有为此table设置任何indexs

对于此查询:

SELECT m1.*
FROM gps m1 LEFT JOIN
     gps m2
     ON m1.driver_id = m2.driver_id AND m1.id < m2.id
WHERE m2.id IS NULL;

您想要 gsp(driver_id, id) 上的索引。您可能已经有了这个索引。

根据您的问题,您将返回 600,000 行。大部分时间可能花在返回行上,而不是生成结果集上。

如果要处理 GIS 数据,请考虑使用 GIS extension。切换到 NO-SQL 解决方案可以解决一些性能问题,但它可能会引入其他问题。在仔细评估系统所需的全部操作之前,您不应该切换。

您可以像这样找到每个 driver 的最新阅读的 id

           SELECT MAX(id) id
             FROM gps
            GROUP BY driver_id

(driver_id, id) 上的索引将有助于该查询。然后这个查询找到每个 driver.

的最新位置
       SELECT a.lat, a.lon, a.driver_id
         FROM gps a
         JOIN (
                  SELECT MAX(id) id
                    FROM gps
                   GROUP BY driver_id
              ) b ON a.id = b.id

专业提示:避免SELECT *对性能关键的查询,尤其是来自大型表的查询。而是提供您需要的列的名称。

专业提示:列越短速度越快,尤其是在大表中。固定长度的列更快,尤其是在大表中。不要使用 varchar(100) 来存储 lat/lon 值。如果这些值来自 GPS,请使用 FLOAT。如果它们来自测量或摄影测量,请使用 DOUBLE。或者考虑使用 MySQL Spatial Data Extensions.