简体   繁体   English

如何索引这个MySQL表用于GEO数据?

[英]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. 由于你的内部SELECTWHERE子句中使用了post_typelatlon ,我建议在那些上添加一个索引。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM