优化此查询的最佳方法是什么?
$tripsNearLocation = mysqli_query($con,
"SELECT * FROM (
SELECT *
, ( 3959 * acos( cos(" . $latRad . ")
* cos( radians( startingLatitude ) )
* cos( radians( startingLongitude )
- (" . $longRad . ") )
+ sin(" . $latRad . ")
* sin( radians( startingLatitude ) ) ) )
AS distance FROM trips
) as query
WHERE distance < 10
ORDER BY distance LIMIT 0 , 10;");
50,000行需要一两秒钟才能完成。我是否应该添加其他查询,以消除甚至不在输入坐标的“接近范围”内的所有行,然后计算剩余的行?假设输入的纬度坐标为67,请排除所有纬度坐标不在65-69之间的行。
还是添加一个“状态列”,如果它们不在同一状态,它将从计算中删除所有行?
还是只处理2秒的计算?我担心数据库可能包含超过100,000行,并且要花费很长时间才能执行。
方案A:对于10万行,您可能只是按纬度缩小而逃脱了。那是,
AND startingLatitude BETWEEN 65 AND 69
。如果您正在考虑使用INDEX(lat,lng),它不是那么简单。看看Lat是否足够好。
方案B:下一个选择将涉及经纬度和经度,以及一个子查询。5.6版将是有益的。就像这样(包括之后INDEX(lat, lng, id)
):
SELECT ... FROM (
SELECT id FROM tbl
WHERE lat BETWEEN...
AND lng BETWEEN... ) x
JOIN tbl USING (id)
WHERE ...;
由于各种原因,B计划仅比A计划略好。
方案C:如果您需要数百万行,则需要使用我的披萨店算法。这涉及到一个存储过程来重复探测,寻找足够的行。它还涉及PARTITION
获得原始的2D索引。
计划A和B是O(sqrt(N))
; 计划C为O(1)
。也就是说,对于计划A和B,如果将行数增加三倍,则将花费的时间增加一倍。计划C不会变慢。(听起来您的代码是O(N)
-行数加倍=时间加倍。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句