微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 MySQL 8.0 执行这个 SELECT 查询比 5.7 慢 1000 多倍

如何解决为什么 MySQL 8.0 执行这个 SELECT 查询比 5.7 慢 1000 多倍

我可以在同一硬件(带有 NVMe SSD 的 Windows 10)上运行 MysqL 5.7 和 8.0 版本。以下查询MysqL 5.7 下的执行速度比 MysqL 8.0 快 1000 多倍:

SELECT `oacode`,ST_asWKB(`shape`) as `shape` FROM 
    (SELECT * FROM oa_bdy WHERE seatname='Barnsley Central') AS `vtable`
    WHERE MBRIntersects(`shape`,ST_GeomFromText('polyGON ((426519 410113,426519 4156675,432073 415667,432073 410113,426519 410113))',27700));

MysqL 5.7 上执行需要 0.016 秒,但在 MysqL 8.0 上需要 19.6 秒。

表使用 MyISAM,oa_bdy 表有 232,296 行,但只有 290 行与内部 WHERE 匹配。一个区别是查询中的“EXPLAIN”从两个版本中产生不同的结果。

MysqL id 选择类型 分区 类型 possible_keys key_len 参考 过滤 额外
v5.7 1 简单 oa_bdy (NULL) 范围 形状 形状 34 (NULL) 1406 10.00 在哪里使用
v8.0 1 简单 oa_bdy (NULL) 全部 (NULL) (NULL) (NULL) (NULL) 232296 10.00 在哪里使用

我对解决此问题的 MysqL 内部结构了解不够,但性能差异非常显着且有害。

大家有什么建议吗?

谢谢。

更新(2021 年 2 月 7 日)。感谢您对空间索引的评论。两个版本的模式是相同的(一个是另一个的副本)并且模式确实包含空间索引。

CREATE TABLE `oa_bdy` (
   `shape` geometry NOT NULL,`oacode` varchar(9) NOT NULL,`seatname` varchar(43) DEFAULT NULL,PRIMARY KEY (`oacode`),SPATIAL KEY `shape` (`shape`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8

一个问题似乎是 MysqL 8 中有一个新行为,它将忽略空间索引(用于查询优化目的),除非列具有已定义的 SRID(而不仅仅是单个单元格)。当8.0下的schema改成

CREATE TABLE `oa_bdy` (
   `shape` geometry NOT NULL SRID 27700,SPATIAL KEY `shape` (`shape`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8

那么8.0下的EXPLAIN与5.7匹配,8.0下的运行时间下降到0.391秒,仍然比MysqL 5.7慢24倍。

对于这种查询,有没有什么办法可以让 MysqL 8.0 下的运行时间与 MysqL 5.7 下的运行时间相似?

解决方法

您的旧数据库上肯定有一个索引,而新数据库上没有。由于新数据库缺少索引,MySQL 满足您查询的唯一方法是将表中的每一行与您的搜索条件进行比较。使用正确的索引,需要比较的行数要少得多。

在 5.7 和 8.0 上执行 SHOW CREATE TABLE oa_bdy,并比较它们。老一辈肯定会提到一个或多个索引。

您可以创建一个索引来帮助处理您通过 doing this ....

向我们展示的查询
CREATE SPATIAL INDEX x_oa_bdy_shape ON oa_bdy(shape);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。