优化 Tinder 类型 mysql 查询

我是mysql的新手,但已经构建了以下查询

  1. 使用 latlong POINTs 表(table pos)查找附近的用户。
  2. 删除已评分的用户(表格轻扫)。
  3. 将结果联接到用户表。

例如,为 id = 1 的用户查找 POINT(95,95) 附近的人(简化纬度值)

SELECT users.id, name, email, gender, birthyear, latlong FROM (
SELECT * FROM (
    # Find nearby users.
    SELECT * FROM pos
        WHERE X(latlong) BETWEEN 90.0 AND 100.0
        AND Y(latlong) BETWEEN 90.0 AND 100.0
) AS nearby WHERE owner NOT IN (
    # Find users already rated.
    SELECT target FROM swipes WHERE owner = 1
) AND id != 1
) AS unratedNearby JOIN users ON unratedNearby.owner = users.id;

这一切都很完美,但我担心这个查询的复杂性以及它将如何扩展。我有一个在桌面上的pos(我意识到这是一种寻找附近用户的次优方式,但准确性在这里并不那么重要)。任何一个用户都可以有无限数量的滑动。SPATIAL KEY 'latlong' ('latlong')

一旦用户和滑动表开始变得非常大,此查询是否会开始分解?除了空间键之外,我还应该使用任何索引吗?


答案 1

对于这个简单的任务,您的查询似乎太复杂了。此外,您查找附近用户的方法对于查找人员任务似乎非常不准确。将此查询与哈弗正弦公式作为距离函数(此函数的示例可以在线轻松找到)

SELECT user_id,name,email,gender,birthyear,latlong,distance(latlong) as      
distance
FROM pos p left join swipes s on p.user_id = s.owner
WHERE target_id is NULL
ORDER by distance asc

此查询可能是错误的,因为您尚未提供创建表语句。但逻辑是正确的。您将用户位置表联接在滑动表上,并获取没有记录的行,而不是按距离对结果进行排序以获取附近的人。


答案 2

缩放是“查找最近点”的问题。朴素解是O(N*N);大多数解决方案都是O(N)。

这是一个解决方案,但它涉及数据的重组。它是O(1)。示例代码位于博客中。


推荐