【发布时间】:2016-04-16 04:26:28
【问题描述】:
基于http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/
以下 SQL 查询返回给定 $radius 内最接近 $lat/$lon 对的城市数组。我添加了另一个join-statement (c.) 以显示每个城市的Country 表中的code3l-列。
总体而言,由于 3Mio 条目的数量,此语句大约需要 1.2sek
SELECT population, AccentCity, Country, code3l, name, City, Region,
Latitude, Longitude, distance, id
FROM (
SELECT z.population,z.id,
z.AccentCity,z.Country, z.City, z.Region,
z.Latitude, z.Longitude,
c.name, c.code3l,
p.radius,
p.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latpoint))
* COS(RADIANS(z.latitude))
* COS(RADIANS(p.longpoint - z.longitude))
+ SIN(RADIANS(p.latpoint))
* SIN(RADIANS(z.latitude)))) AS distance
FROM worldpopulation AS z
JOIN (
SELECT '.$lat.' AS latpoint, '.$lon.' AS longpoint,
'.$radius.' AS radius, 111.045 AS distance_unit
) AS p ON 1=1
JOIN (
SELECT * FROM countries
) AS c ON c.code2l = z.Country
WHERE
z.population IS NOT NULL
AND z.latitude
BETWEEN p.latpoint - (p.radius / p.distance_unit)
AND p.latpoint + (p.radius / p.distance_unit)
AND z.longitude
BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
) AS d
WHERE distance <= radius
ORDER BY distance ASC';
除此之外,我还需要添加一些count(*)-statements 来返回每个城市的乘客数量。所以我试着像这样添加这些:
SELECT population, AccentCity, Country, code3l, name, City, Region,
Latitude, Longitude, distance,id,
(select count(*) from passengers where city_id = d.id) AS passenger,
(select count(*) from passengers where city_id = d.id AND
start = "'.$icao.'") AS passengerFromHere,
(select count(*) from passengers where city_id = d.id AND
destination = "'.$icao.'") AS passengerToHere
FROM (
SELECT z.population,z.id,
...
但名为 passengers 的表增长很快,语句的整体执行时间也随之增长
我有办法加入沉重的passengers 表,在更好的执行时间内获得相同的结果(城市数组及其各自的乘客)
【问题讨论】:
-
尝试使用
count(id)而不是count(*),因为它会选择表格中的所有内容。您应该始终避免使用 *. -
性能随容量下降 - 这清楚地表明您需要能够支持数据增长的良好硬件。在您达到其中一台设备的限制之前,您只能做这么多。现在,您可以尝试 hack 和 slash 等等,但最终 - 即使是最好的代码或查询也达到了硬件限制。
-
发现这篇有趣的文章:link。尝试在配置文件中使用这些值:
query_cache_size = 268435456query_cache_type=1query_cache_limit=1048576 -
@AlexanderTeitelboym 注意:斜体如果您的应用程序频繁更新表,那么查询缓存将不断被清除,您将不会得到太多或任何好处”不幸的是,乘客表会经常更新。无论如何,感谢您的阅读
标签: mysql join count large-data-volumes