0

一般来说,我对 MySQL 和数据库非常陌生,但我的查询似乎需要很长时间。我正在使用纬度和经度坐标从另一个位置 5 英里范围内的大约 700,000 个位置数据库中查找位置。问题是,查询需要 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 中的哪个位置添加它?

4

3 回答 3

1

该查询将 seq 扫描整个表,因为它实际上没有不是从计算值(距离)派生的过滤器。添加一个按索引列过滤的 where 子句肯定有助于消除一些开销,但前提是数据库认为表中有足够的数据来保证使用索引而不是表。因此,请确保您也对其进行分析。

查询中的距离逻辑非常丑陋,但我可以理解为什么每次从表中选择时您都不想通过线路传输 700k+ 行。看起来您可能正在进行空间计算,并且可能明智地研究空间数据类型和索引。

Ed:另外,你关于where子句的问题......

select fields [aggregate fields]
from table
where where clause
group by fields
having having clause
于 2012-05-30T05:11:40.923 回答
0

我对这种类型的查询通常是如何进行的一无所知,因此请随意忽略我的建议,但假设您的应用程序要接受输入 {lat,lon} 并在每个方向(北、东、南部和西部)。然后,您的查询只能选择那些在上限和下限之间具有 lat 和 long 的记录。

您仍然需要进行距离计算,但您将消除可能无法匹配的记录,因此您应该减少查询的开销。此外,如果你有一个关于 lat 和 long 的索引,那么 mysql 应该能够使用这些。

正如我所说,我可能误解了几何形状,我在该领域没有经验,但除了其他建议之外,它可能是一个有用的优化。

于 2012-05-30T10:48:52.043 回答
0

为什么要在查询中进行计算?像这样的逻辑不应该在 DAL 中。

我建议只获取您需要的列,然后在您的代码中进行计算,这样您就可以只计算没有经纬度的部分(例如 SIN(44.4726 * PI() / 180)),然后只需循环结果并酌情添加纬度和经度。

于 2012-05-30T05:05:51.080 回答