优化位置搜索mysql脚本

时间:2015-07-15 15:44:50

标签: php mysql wordpress query-optimization

我正在尝试实施一个"找到最近的位置"从给定的纬度和经度使用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网站上进行处理,有时甚至会出现超时错误。

在那里,我可以优化上面的代码,以便它运行得更快?

2 个答案:

答案 0 :(得分:0)

如果用显式group by替换join,这可能会更快。这假设每个帖子最多只有一个纬度和经度:

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)上的索引一样。

答案 1 :(得分:0)

我通过创建一个新表来解决我的问题,该表包含我试图从联接解决方案中提取的字段。

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

此解决方案已将我的70s查询转换为0.13s,因此我对此解决方案感到满意。

然后我添加了一个post_save动作挂钩来更新wp_cbk_location每次我保存一个帖子所以我创建的新表保持uptodate。

我还有一个问题,我将提交一个新问题。我在post__in中可以拥有的数组中有多少个ID?