我的表现在是这样的:
CREATE TABLE IF NOT EXISTS `x_geodata` (
`post_id` int(11) NOT NULL,
`post_type` varchar(20) NOT NULL,
`lat` float(10,6) NOT NULL,
`lng` float(10,6) NOT NULL,
PRIMARY KEY (`post_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;如何正确有效地为该表建立索引?
对此表运行的唯一查询如下所示:
if(!empty($_SESSION['s_property_radius'])) {$dist = $_SESSION['s_property_radius'];}else{$dist = 50;}
$orig_lat = $_SESSION['s_property_address_lat'];
$orig_lon = $_SESSION['s_property_address_lng'];
$lon1 = $orig_lon - $dist / abs( cos( deg2rad( $orig_lat ) ) * 69 );
$lon2 = $orig_lon + $dist / abs( cos( deg2rad( $orig_lat ) ) * 69 );
$lat1 = $orig_lat - ( $dist / 69 );
$lat2 = $orig_lat + ( $dist / 69 );
$sql = "
SELECT `t`.`post_id`, 3956 * 2 * ASIN( SQRT( POWER( SIN( ( ".$orig_lat." - `t`.`lat` ) * pi() / 180 / 2), 2 ) + COS( ".$orig_lat." * pi() / 180) * COS( `t`.`lat` * pi() / 180 ) * POWER( SIN( ( ".$orig_lon." - `t`.`lng` ) * pi() / 180 / 2 ), 2 ) ) ) AS `distance` FROM (
SELECT `post_id`, `lat`, `lng` FROM `x_geodata` WHERE `post_type` = 'some post type' AND `lng` BETWEEN '".$lon1."' AND '".$lon2."' AND `lat` BETWEEN '".$lat1."' AND '".$lat2."'
) AS `t` HAVING `distance` <= ".$dist."
";查询检查以确保我们查看的是正确的post类型,然后对lat和lng进行平方半径检查。然后,通过圆形半径检查运行返回的结果。
我正在寻找的是更新的CREATE TABLE SQL或UPDATE TABLE SQL,以获得正确的索引。
任何帮助都是非常感谢的。
编辑:根据arnep答案对我的问题进行了解释,我得到了以下结果:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
2 DERIVED zch_geodatastore range post_type post_type 70 NULL 3 Using where虽然不知道这是什么意思。
发布于 2011-05-17 21:25:09
由于您的内部SELECT在WHERE子句中使用了post_type、lat和lon,因此我建议对它们建立一个索引。
使用EXPLAIN [QUERY]查看是否使用了索引,以及从中获得了什么好处。
发布于 2011-05-06 00:30:50
MySQL为MySQL提供了特殊的SPATIAL密钥。
请参阅:http://dev.mysql.com/tech-resources/articles/4.1/gis-with-mysql.html
引用自:http://dev.mysql.com/doc/refman/5.1/en/create-index.html
MyISAM、InnoDB、NDB和归档存储引擎支持空间列,如(点和几何图形。(第11.17节“空间扩展”描述了空间数据类型。)
空间键包括:
·仅适用于MyISAM表格。为其他存储引擎指定空间索引会导致错误。
·索引列必须不为空。
·在MySQL 5.1中,禁止使用列前缀长度。每列的全宽被编入索引。
你知道这是一个专门针对这类问题的https://gis.stackexchange.com/论坛,
我建议你也把你的问题贴在那里(重复)。
https://stackoverflow.com/questions/5900963
复制相似问题