2017-04-13 78 views
0

我正在寻找能够找到近似匹配(假设在20米范围内)从给定点到点的行。它可以工作,但不使用索引。Mysql空间索引未使用

我想利用这个表上的空间索引,但它似乎并没有被使用(解释命令给我“possible_keys”= null)。

下列要求:

  • 的MySQL 5.7.17
  • 表:

    CREATE TABLE `geoDirections` (
        `id` int(11) NOT NULL, 
        `from` point NOT NULL, 
        `to` point NOT NULL, 
    ) ENGINE=InnoDB; 
    ALTER TABLE `geoDirections` 
        ADD PRIMARY KEY (`id`), 
        ADD SPATIAL KEY `from` (`from`), 
        ADD SPATIAL KEY `to` (`to`); 
    
  • 以防万一百万行插入

我试了一下:

  • 使用ST_Contains

    EXPLAIN SELECT 
        g.`from` 
    FROM 
        geoDirections g 
    WHERE 
        ST_Contains(ST_Buffer(
          ST_GeomFromText('POINT(-2.00751 48.6547)', 4326), (0.00001*20)), g.`from`) = 1 
        AND 
         ST_Contains(ST_Buffer(
          ST_GeomFromText('POINT(-2.05757 48.6338)', 4326), (0.00001*20)), g.`to`) = 1 
    

使用计算出的距离使我

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra  | 
    | 1 | SIMPLE  | g  |  null  | ALL |  null  | null | null | null | 994867 | 100.00 | Using where | 
  • EXPLAIN SELECT 
        X(g.`from`),Y(g.`from`), g.*, (
         6373 * acos (
         cos (radians(-2.00751)) 
         * cos(radians(X(g.`from`))) 
         * cos(radians(Y(g.`from`)) - radians(48.6547 )) 
         + sin (radians(-2.00751)) 
         * sin(radians(X(g.`from`))) 
        ) 
    ) AS distanceFrom 
    FROM geoDirections g 
    HAVING distanceFrom < 0.02 
    

给我

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | 
    | 1 | SIMPLE  | g  |  null  | ALL |  null  | null | null | null | 994867 | 100.00 | null | 
  • 甚至一些如

    EXPLAIN SELECT 
        X(g.`from`),Y(g.`from`), g.* 
    FROM geoDirections g 
    WHERE X(g.`from`) = -2.00751 
    

简单给我

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra  | 
    | 1 | SIMPLE  | g  |  null  | ALL |  null  | null | null | null | 994867 | 100.00 | Using where | 
  • 试图转换的InnoDB在MyISAM(较旧版本的InnoDB应该wheren't支持空间索引)

我缺少什么?

+0

嗯...我不知道如果我的[_code_(http://mysql.rjweb.org/doc.php/latlng)将在修复后,击败它。 –

回答

1

Bug #76384 Spatial index not used when checking return values explicitly

尝试:

mysql> DROP TABLE IF EXISTS `geoDirections`; 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE `geoDirections` (
    -> `id` INT(11) NOT NULL, 
    -> `from` POINT NOT NULL, 
    -> `to` POINT NOT NULL 
    ->) ENGINE=InnoDB; 
Query OK, 0 rows affected (0.01 sec) 

mysql> ALTER TABLE `geoDirections` 
    ->  ADD PRIMARY KEY (`id`), 
    ->  ADD SPATIAL INDEX (`from`), 
    ->  ADD SPATIAL INDEX (`to`); 
Query OK, 0 rows affected (0.00 sec) 
Records: 0 Duplicates: 0 Warnings: 0 

mysql> EXPLAIN SELECT `g`.`from` 
    -> FROM `geoDirections` `g` 
    -> WHERE 
    ->  ST_Contains(ST_Buffer(
    ->   ST_GeomFromText('POINT(-2.00751 48.6547)', 4326), (0.00001 * 20)), `g`.`from`) 
    ->  AND 
    ->  ST_Contains(ST_Buffer(
    ->   ST_GeomFromText('POINT(-2.05757 48.6338)', 4326), (0.00001 * 20)), `g`.`to`)\G 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: g 
    partitions: NULL 
     type: ALL 
possible_keys: from,to 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 1 
    filtered: 100.00 
     Extra: Using where 
1 row in set, 1 warning (0.00 sec) 
+0

我让我疯狂......感谢您发现错误。 MyISAM上的同样错误 – Axi

+0

@Axi - 现在运行速度有多快? –

+0

@RickJames我没有检查,但它现在使用索引 – Axi