0

抱歉,如果这已经被回答(如果有的话,我相信有人会向我抛出链接)。前段时间想了一个类似的问题,但现在找不到了。

因此,对于这个问题:我正在为我正在开发的网站构建用户搜索,其中一个搜索条件将基于与搜索用户的距离。我已经有一张美国邮政编码及其对应的经纬度表。我还想出了如何确定边界框(最大纬度/最小纬度 - 最大长度/最小长度)以确定哪些拉链符合标准(我们不会担心精确的半径。地理正方形暂时够用了)。我的问题 - 我应该如何构建查询以优化速度?我是不是该:

  • 执行所需的数学以确定边界框,然后查询邮政编码表以查找所有潜在候选邮政编码,然后搜索具有这些邮政编码的用户?

或者

  • 确定纬度/经度边界框,将 zip 表与用户表连接起来,并返回纬度/经度介于参数之间的用户的结果?

我想第二种方法会更快,但我没有支持证据/具体经验表明它会。我知道足够多的 SQL 来解决问题,但我对它还是有点陌生​​,并且对于不同类型操作的相对性能一无所知。

谢谢你的时间!

4

2 回答 2

2

我相信您的最终查询应如下所示:

-- compute @minLat, @maxLat, @minLon, @maxLon

SELECT users.*
FROM users
JOIN locations ON locations.id = users.location
WHERE locations.latitude BETWEEN @minLat AND @maxLat
AND locations.longitude BETWEEN @minLon AND @maxLon

所以在这种情况下,我不明白你的担忧,因为一切都是一次性发生的。查询优化器通常比任何人都知道JOIN首先执行哪个。

如果您想实现更复杂的计算来确定邮政编码是否在范围内,那么我宁愿首先建立一个邮政编码列表,然后匹配居住在这些地区的用户。

这假设计算邮政编码是否在搜索范围内是操作中成本最高的部分。因此,我更喜欢使用尽可能小的数据集(即仅邮政编码,而不是邮政编码 + 用户)运行此计算。即使在这种情况下,查询优化器也可能会为您做出正确的选择。

于 2012-06-28T21:35:26.687 回答
1

您描述的两种算法可以这样示意性地描述:

A INNER JOIN B WHERE A satisfies condition

(A WHERE A satisfies condition) INNER JOIN B

前者只是一个连接(条件可以是连接条件或 WHERE 条件,但这对于 INNER JOIN 和 MySQL 并不重要)。

后者涉及子查询。您的描述似乎假设首先计算子查询,然后是连接,但通常情况并非如此。首先评估内部连接,然后评估子查询,这很可能会为您提供与第一种情况相同的执行计划。

所以从性能的角度来看,这两种方法似乎没有什么不同,您应该专注于选择一种最容易阅读和维护的方法,并在这一天到来时对其进行分析和优化。

于 2012-06-28T21:35:55.283 回答