我在Ubuntu和;Windows 10和我都很困惑,为什么这个查询运行得这么慢(大约15秒),而且没有利用空间索引.我使用的MBRContains几乎与MySQL文档11.4.11 Using Spatial Indexes中描述的完全一样.如果包含在POLYGON(框)中,则表location_coordinate有735k行POINT类型的横向/纵向坐标搜索.

查询:

SELECT long_lat_id, ST_Latitude(long_lat), ST_Longitude(long_lat)
FROM location_coordinate
WHERE MBRContains(ST_GeomFromText(
    'POLYGON((
        40.79607446677 -73.919978196147, 
        40.70923553323 -73.919978196147, 
        40.70923553323 -74.034611803853, 
        40.79607446677 -74.034611803853, 
        40.79607446677 -73.919978196147))', 4326)
    , long_lat);

解释查询

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: location_coordinate
   partitions: NULL
         type: ALL
possible_keys: long_lat
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 735118
     filtered: 100.00
        Extra: Using where
1 row in set, 1 warning (0.00 sec)

表定义和解释

CREATE TABLE location_coordinate (
    long_lat_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
    long_lat POINT NOT NULL SRID 4326,  
    PRIMARY KEY (long_lat_id),
    SPATIAL INDEX (long_lat)
);


mysql> EXPLAIN location_coordinate;
+--------------+--------------------+------+-----+---------+----------------+
| Field        | Type               | Null | Key | Default | Extra          |
+--------------+--------------------+------+-----+---------+----------------+
| long_lat_id  | mediumint unsigned | NO   | PRI | NULL    | auto_increment |
| long_lat     | point              | NO   | MUL | NULL    |                |
+--------------+--------------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

推荐答案

Rick James comment之后,我打算提交一个bug报告,但事实证明这是MySQL 8.0.29中公认的bug

https://bugs.mysql.com/bug.php?id=107320开始

MySQL 8.0.31变更日志(log)中记录的修复程序如下:

Upgrading to MySQL 8.0.29 led to issues with existing spatial
indexes. The root cause of the problem was a change in how
geographic area computations were performed by the included
Boost library, which was upgraded to version 1.77.0 in MySQL
8.0.29. We fix this by ensuring that we accommodate the new
method whenever such computations are performed.

关闭

临时修复方法是在查询中使用FORCE INDEX ()函数.这将查询时间从15秒减少到.062秒.

SELECT long_lat_id, ST_Latitude(long_lat), ST_Longitude(long_lat)
FROM location_coordinate FORCE INDEX(long_lat)
WHERE MBRContains(ST_GeomFromText(
    'POLYGON((
        40.79607446677 -73.919978196147, 
        40.70923553323 -73.919978196147, 
        40.70923553323 -74.034611803853, 
        40.79607446677 -74.034611803853, 
        40.79607446677 -73.919978196147))', 4326)
    , long_lat);

Mysql相关问答推荐

错误:数据包顺序错误.GET:0预期:10 node JS MySQL

在MySQL的join查询中进行计算

为什么用PyMySQL构建的json返回结果会出现重复?

根据 Power Query 中的条件替换值

如何在 MySQL 中使用从 SELECT IF 返回的布尔值

获取 MySQL 中每一行之间负差的总和

如何 Select 具有最新的 2 个日期字段的行?

MYSQL:范围匹配与周年纪念日

即使我的约束是正确的,如何解决 errno: 150 外键约束形成错误?

是否可以从 .SQL 文件中计算表中的行数?

估计行数 SQL

mysql从另一个表中 Select 不相等的值

PHP PDO 与普通 mysql_connect

通过数据库级​​别本身的查询反序列化

如何为 php 启用 mysqlnd?

用户 'User'@'%' 和 'User'@'localhost' 不一样吗?

如何在 MySQL 中删除此索引?

MySQL 1062 - 键 'PRIMARY' 的重复条目 '0'

如果另一列为空,则 Select 一列

如何使用 Java 更改数据库连接中的 MySQL 时区?