一般来说,我对MySQL和数据库都很陌生,但我的查询似乎需要很长时间。我正在使用经度和经度坐标从大约70万个位置数据库中查找距离另一个位置不到5英里的位置。问题是,查询需要2.12秒,我担心一旦开始出现流量,MySQL就会堵塞。下面是我的代码:
SELECT *,((ACOS(SIN(44.4726 * PI() / 180) * SIN(lat * PI() / 180) + COS(44.4726 * PI() / 180) * COS(lat * PI() / 180) * COS((-93.1785 - lon) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance FROM locations HAVING distance<=5 ORDER BY distance ASC LIMIT 30;我已经为经度和经度字段建立了索引,但这仍然需要很长时间。对于我要求服务器做的事情,这是预期的吗?我是否可以通过添加
WHERE state = "$state"如果是这样,我应该在Select中将其添加到哪里?
发布于 2012-05-30 13:11:41
该查询将顺序扫描整个表,因为它实际上没有一个过滤器不是从计算值(距离)派生出来的。添加一个按索引列过滤的where子句肯定有助于消除一些开销,但前提是DB认为表中有足够的数据可以保证使用索引而不是表。因此,确保您也对其进行了分析。
查询中的距离逻辑非常丑陋,但是我可以理解为什么每次从表中选择时都不希望通过网络传输700k+行。看起来您可能正在进行空间计算,调查空间数据类型和索引可能是明智的。
艾德:还有,你关于where子句的问题...
select fields [aggregate fields]
from table
where where clause
group by fields
having having clause发布于 2012-05-30 13:05:51
为什么要在查询中进行计算?这样的逻辑不应该出现在DAL中。
我建议您只获取所需的列,然后在代码中执行calculate,这将允许您只计算没有lat和long once的部分(例如SIN(44.4726* PI() / 180) ),然后循环结果并根据需要添加lat和long。
发布于 2012-05-30 18:48:52
我不知道这种类型的查询通常是如何完成的,所以可以忽略我的建议,但是假设您的应用程序接受输入{lat,lon},并在每个方向(北、东、南和西)将其扩展5英里。然后,您的查询可以只选择那些在上界和下界之间具有lat和long的记录。
您仍然需要进行距离计算,但是您将排除不可能匹配的记录,因此,您应该减少查询的开销。此外,如果您在lat和long上有索引,那么mysql应该能够使用它们。
我可能误解了几何学,就像我说的,我在这个领域没有经验,但这可能是一个有用的优化,除了其他建议。
https://stackoverflow.com/questions/10810173
复制相似问题