600000 位用户的 GPS table
GPS table of 600000 users
我正在使用 mysql
。我的编程语言是 php
.
我有 600.000 个用户,我每 10 秒通过 cell-phone 的 gps 获得这些用户中的 lat
和 lon
一次。
我对此的一些疑问table:
- 最近的具有特定
lan
和 lon
的用户。
- 每分钟获取每个用户的最后
lan
和 lon
。
我的一些查询需要 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.
我正在使用 mysql
。我的编程语言是 php
.
我有 600.000 个用户,我每 10 秒通过 cell-phone 的 gps 获得这些用户中的 lat
和 lon
一次。
我对此的一些疑问table:
- 最近的具有特定
lan
和lon
的用户。 - 每分钟获取每个用户的最后
lan
和lon
。
我的一些查询需要 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 使用像 我们先讨论MySQL修复。Cloud Bigtable
这样的第三方是个好主意吗?
有什么解决办法吗?
我的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.