【发布时间】:2016-03-10 20:07:12
【问题描述】:
我正在使用“WP_GeoQuery”类,它扩展了 WP_Query,因此我们可以通过英国邮政编码(经纬度坐标)搜索帖子。它运行良好,但速度非常慢。
在使用以下代码扩展 WP_Query 以加快 MySQL 请求时,我可以采取哪些步骤?
class WP_GeoQuery extends WP_Query
{
private $_search_latitude = NULL;
private $_search_longitude = NULL;
private $_radius = NULL;
/**
* Constructor - adds necessary filters to extend Query hooks
*/
public function __construct($args = array())
{
// Extract Latitude
if(!empty($args['latitude'])) { $this->_search_latitude = $args['latitude']; }
// Extract Longitude
if(!empty($args['longitude'])) { $this->_search_longitude = $args['longitude']; }
// Extract Longitude
if(!empty($args['radius'])) { $this->_radius = $args['radius']; }
// unset lat/long
unset($args['latitude'], $args['longitude'], $args['radius']);
// Extract Post type
if(!empty($args['post_type'])) { $this->_post_type = $args['post_type']; }
add_filter('posts_fields', array($this, 'posts_fields'), 10, 2);
add_filter('posts_join', array($this, 'posts_join'), 10, 2);
add_filter('posts_where', array($this, 'posts_where'), 10, 2);
add_filter('posts_orderby', array($this, 'posts_orderby'), 10, 2);
add_filter('posts_distinct', array($this, 'posts_distinct'), 10, 2);
// Run query
parent::query($args);
// Remove filters so only WP_GeoQuery queries this way
remove_filter('posts_fields', array($this, 'posts_fields'));
remove_filter('posts_join', array($this, 'posts_join'));
remove_filter('posts_where', array($this, 'posts_where'));
remove_filter('posts_orderby', array($this, 'posts_orderby'));
remove_filter('posts_distinct', array($this, 'posts_distinct'));
} // END public function __construct($args = array())
/**
* Return only distinct results
*/
function posts_distinct()
{
return "DISTINCT";
} // END public function posts_distinct()
/**
* Selects the distance from a haversine formula
*/
public function posts_fields($fields)
{
global $wpdb;
if(!empty($this->_search_latitude) && !empty($this->_search_longitude))
{
$fields .= sprintf(", ( 3959 * acos(
cos( radians(%s) ) *
cos( radians( latitude.meta_value ) ) *
cos( radians( longitude.meta_value ) - radians(%s) ) +
sin( radians(%s) ) *
sin( radians( latitude.meta_value ) )
) ) AS distance ", $this->_search_latitude, $this->_search_longitude, $this->_search_latitude);
}
$fields .= ", latitude.meta_value AS latitude ";
$fields .= ", longitude.meta_value AS longitude ";
$fields .= ", location.meta_value AS location ";
return $fields;
} // END public function posts_join($join, $query)
/**
* Makes joins as necessary in order to select lat/long metadata
*/
public function posts_join($join, $query)
{
global $wpdb;
$join .= " INNER JOIN {$wpdb->postmeta} AS latitude ON {$wpdb->posts}.ID = latitude.post_id ";
$join .= " INNER JOIN {$wpdb->postmeta} AS longitude ON {$wpdb->posts}.ID = longitude.post_id ";
$join .= " INNER JOIN {$wpdb->postmeta} AS location ON {$wpdb->posts}.ID = location.post_id ";
return $join;
} // END public function posts_join($join, $query)
/**
* Adds where clauses to compliment joins
*/
public function posts_where($where)
{
$where .= ' AND latitude.meta_key="postcode_lat" ';
$where .= ' AND longitude.meta_key="postcode_lng" ';
$where .= ' AND location.meta_key="individual_details_postcode" ';
if(!empty($this->_search_latitude) && !empty($this->_search_longitude) && !empty($this->_radius))
{
if(is_numeric($this->_radius))
{
$where .= sprintf(' HAVING distance <= %s ', $this->_radius);
}
}
return $where;
} // END public function posts_where($where)
/**
* Adds where clauses to compliment joins
*/
public function posts_orderby($orderby)
{
if(!empty($this->_search_latitude) && !empty($this->_search_longitude))
{
$orderby = " distance ASC, " . $orderby;
}
return $orderby;
} // END public function posts_orderby($orderby)
}
【问题讨论】:
-
在您的 WP 安装中,post_meta 中有多少帖子具有 lat/long 值?许多?数百?几万?
-
目前只有两个帖子。这目前处于测试阶段。尽管我有使用 WordPress 进行开发的经验,但我对 MySQl 优化的知识缺乏,我假设这是该查询的速度存在问题的地方。默认的 WordPress 搜索非常快,但是一旦我使用这个修改 WP_Query 的类,即使只有两个要查询的帖子,加载也需要 1 分钟以上。
-
我一直在考虑你的问题。很奇怪,只查询两个纬度/经度点需要这么长时间。我想知道您是否可以在查询运行时使用 phpmyadmin 或其他 MySQL 客户端访问您的 MySQL 实例, 使用
SHOW FULL PROCESSLIST检索查询文本,然后在此处发布查询文本。 -
你怎么称呼搜索?
标签: mysql latitude-longitude wordpress