mysql geolat geolng 多索引查询

mysql geolat geolng multi indexed query

我有一个 table,其中包含字段 'lat' 和 'lng'。两者几乎都是连续的,这意味着它们不会重复太多。这让我相信为 lat 和 lng 制作多列索引不会真正帮助我。我想做的是:

同时对纬度和经度建立索引,然后执行如下查询:

select from tableName where 
lat >= 13.1232 and lat <=14.123 and 
lng >=-80.123 and lng <=-79.232 and 
name like '%greg%'

并让 mysql 执行此过程:

  1. select 14.1232 和 13.123 之间的所有 LAT(这应该被索引,并且很快)

  2. 在步骤#1 找到的组中,执行步骤#2:找到 lngs <=-80.123和 lngs>= -79.232(这也应该被索引并且非常快)

3.在步骤#1和#2创建的组中...执行更耗时的关键字搜索。

我该怎么做?我很确定查询的第一部分(索引纬度)正在为我缩小范围……但在那之后我不确定……这就是我一直在努力寻找的东西文档

如果您绝对希望每个 where 子句都限制结果集,那么您可以尝试这样的操作,但是 sql 优化器可能会在幕后改变一些事情。我认为一两个好的指数仍然是你最好的选择,但我相信这就是你所要求的。我推荐解释计划来优化您的查询。

select * from
(
    select * from 
        (
        select * from tableName 
        where lat >= 14.1232 and lat <=13.123 
        )
    where lng >=-80.123 and lng <=-79.232
)
where name like '%greg%'

MySQL 像大多数实现一样处理传统的 B 树索引:索引帮助 索引中最左边列的范围条件。

我用的类比是电话簿。如果我搜索特定的姓氏,名字对,如 "Smith, John" 索引会有所帮助。我搜索姓氏 "Smith" 很快,而在 Smiths 内部,搜索 "John" 也很快。

但是如果我搜索像 "all people whose last name begins with 'S'" 这样的范围条件,那么我会得到电话簿的一个子集,但并不是所有名为 "John" 的人都被排序在一起。它们分散在我根据姓氏选择的子集中。

正是出于这个原因,MySQL 搜索 B 树索引直到第一个范围条件,然后不再使用该索引。您仍然可以为另一个维度设置条件,但它会手动搜索与第一个维度匹配的所有行。

换句话说,即使你在(lat, long)上有复合索引,MySQL也不会使用索引的long部分:

select ... from tableName 
where lat >= 14.1232 and lat <=13.123 /* index-assisted */
  and lng >=-80.123 and lng <=-79.232 /* full scan */
  and name like '%greg%'              /* pattern search never uses index anyway */

(顺便说一句,你的纬度条件永远不会像你写的那样是真的,但我假设你的意思是要反转的数字。)

这使得做纬度和经度条件的效率低下,因为两者都在搜索一个值的范围。

因此,MySQL 有另一种索引,它不是 B 树索引。这是一个 SPATIAL 索引,它确实支持多个范围条件。

CREATE TABLE mytable (
  name TEXT NOT NULL, 
  coord POINT NOT NULL,
  SPATIAL INDEX (coord)
);

INSERT INTO mytable (name, coord) 
VALUES ('name', ST_GeomFromText('POINT(14.0 -80)'));

SELECT name FROM mytable 
WHERE MBRContains(
  ST_GeomFromText('Polygon((
    13.123 -80.123,
    14.1232 -80.123,
    14.1232 -79.232,
    13.123 -79.232,
    13.123 -80.123))'),
  coord);

是的,这更复杂,但这是获得真正的索引优化 latitude/longitude 搜索的唯一方法。

在此处阅读更多相关信息:http://dev.mysql.com/doc/refman/5.7/en/using-spatial-data.html