2017-04-13 76 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