[英]How to INDEX this MySQL table for use with GEO data?
My table currently stands like this: 我的表目前如下:
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;
How do I correctly and efficiently INDEX this table? 我如何正确有效地索引此表?
The only query ran on this table is as follows: 在此表上运行的唯一查询如下:
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."
";
The query checks to make sure we are looking at the correct post type and then does a square radius check on the lat and lng. 查询检查以确保我们正在查看正确的帖子类型,然后在lat和lng上进行方形半径检查。 The returned results are then run through a circular radius check.
然后返回的结果通过圆形半径检查。
What I'm looking for is updated CREATE TABLE SQL or UPDATE TABLE SQL to get this INDEXED correctly. 我正在寻找的是更新CREATE TABLE SQL或UPDATE TABLE SQL以正确获得此INDEXED。
Any help is greatly appreciated. 任何帮助是极大的赞赏。
EDIT: Did an EXPLAIN on my query based on arnep answer and I got this: 编辑:根据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
No idea what it means though... 不知道它意味着什么......
MySQL has got special SPATIAL
keys for MySQL. MySQL有MySQL的特殊
SPATIAL
密钥。
See: http://dev.mysql.com/tech-resources/articles/4.1/gis-with-mysql.html 请参阅: http : //dev.mysql.com/tech-resources/articles/4.1/gis-with-mysql.html
And a quote from: http://dev.mysql.com/doc/refman/5.1/en/create-index.html 引用自: http : //dev.mysql.com/doc/refman/5.1/en/create-index.html
The MyISAM, InnoDB, NDB, and ARCHIVE storage engines support spatial columns such as (POINT and GEOMETRY. (Section 11.17, “Spatial Extensions”, describes the spatial data types.)
MyISAM,InnoDB,NDB和ARCHIVE存储引擎支持空间列,例如(POINT和GEOMETRY。 (第11.17节“空间扩展”,描述空间数据类型)。
Spatial keys are: 空间键是:
•Available only for MyISAM tables. •仅适用于MyISAM表。 Specifying SPATIAL INDEX for other storage engines results in an error.
为其他存储引擎指定SPATIAL INDEX会导致错误。
•Indexed columns must be NOT NULL. •索引列必须为NOT NULL。
•In MySQL 5.1, column prefix lengths are prohibited. •在MySQL 5.1中,禁止列前缀长度。 The full width of each column is indexed.
索引每列的全宽。
Did you know that is a special https://gis.stackexchange.com/ forum for these kinds of questions, 你知道这是一个特殊的https://gis.stackexchange.com/论坛,针对这些问题,
I recommend you (double) post your question there as well. 我建议你(双)在那里发布你的问题。
As your inner SELECT
uses post_type
, lat
and lon
in WHERE
clause I would recommend to put an index on those. 由于你的内部
SELECT
在WHERE
子句中使用了post_type
, lat
和lon
,我建议在那些上添加一个索引。
Use EXPLAIN [QUERY]
to see if the index is used and what benefit you get from it. 使用
EXPLAIN [QUERY]
查看是否使用了索引以及从中获得了什么好处。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.