优化位置搜索mysql脚本
Posted
技术标签:
【中文标题】优化位置搜索mysql脚本【英文标题】:Optimise location search mysql script 【发布时间】:2015-07-15 15:44:49 【问题描述】:我正在尝试使用 mysql 从给定的纬度和经度实现“查找最近的位置”。我的 wordpress 网站中存储了 8000 个位置。
我设法写了这个:
SELECT
b.ID,
SQRT( POW(69.1 * (b.latitude - 51.5073509), 2) + POW(69.1 * (-0.1277583 - b.longitude) * COS(b.latitude / 57.3), 2)) AS distance
FROM
wp_posts a
LEFT JOIN
(
SELECT
post_id AS ID,
MAX(CASE WHEN meta_key = 'theme_directory_map_latitude' THEN meta_value ELSE NULL END) AS latitude,
MAX(CASE WHEN meta_key = 'theme_directory_map_longitude' THEN meta_value ELSE NULL END) AS longitude
FROM
wp_postmeta
WHERE
meta_key = 'theme_directory_map_latitude' OR meta_key = 'theme_directory_map_longitude'
GROUP BY
post_id
) b ON a.ID = b.ID
WHERE
a.post_type = 'directory'
HAVING
distance < 30
ORDER BY
distance
上面的脚本可以满足我的需要,但是在我的 weordpress 网站上处理它需要很长时间,有时我什至会出现超时错误。
有没有什么地方可以优化上面的代码,让它运行得更快?
【问题讨论】:
索引,反向查询,不使用wordpress?这更适合codereview.stackexchange.com 这个问题可能适合Code Review,只要 (a) 您的代码按预期工作,(b) 您的代码是真实代码,而不是示例代码,并且 (c) 您的代码包含在问题的正文中。如果您希望通过同行评审来改进代码的各个方面,请将其发布在 Code Review 上。 【参考方案1】:如果您将group by
替换为显式join
s,这可能会更快。这假设每个帖子最多有一个纬度和经度:
SELECT b.ID,
SQRT( POW(69.1 * (lat.meta_value - 51.5073509), 2) + POW(69.1 * (-0.1277583 - lng.meta_value) * COS(lat.meta_value / 57.3), 2)) AS distance
FROM wp_posts p JOIN
wp_postmeta lat
on lat.post_id = p.id and lat.meta_key = 'theme_directory_map_latitude'
wp_postmeta lng
on lng.post_id = p.id and lng.meta_key = 'theme_directory_map_longitude'
WHERE p.post_type = 'directory'
HAVING distance < 30
ORDER BY distance;
wp_posts(post_type, id)
上的索引也会有所帮助。 wp_postmeta(post_id, meta_key, meta_value)
上的索引也是如此。
【讨论】:
【参考方案2】:我通过创建一个新表解决了我的问题,该表包含我试图从连接解决方案中提取的字段。
SELECT
post_id AS ID,
featured,
IF(latitude <> '', SQRT( POW(69.1 * (latitude - ".$lat."), 2) + POW(69.1 * (".$lng." - longitude) * COS(latitude / 57.3), 2)), '') AS distance
FROM
wp_cbk_location
HAVING
(distance < ".$radius." AND distance <> '') OR featured = 1
ORDER BY
distance
这个解决方案将我 70 年代的查询变成了 0.13 秒,所以我对这个解决方案很满意。
然后我添加了一个 post_save 操作挂钩,以在我每次保存帖子时更新 wp_cbk_location,以便我创建的新表保持最新。
我还有一个问题,我将提交一个新问题。我可以在 post__in 中拥有的数组中的 id 数量是否有限制?
【讨论】:
以上是关于优化位置搜索mysql脚本的主要内容,如果未能解决你的问题,请参考以下文章