[英]Why is MySQL 8.0 over 1000 times slower than 5.7 to execute this SELECT query
I'm able to have both versions 5.7 and 8.0 of MySQL running on the same hardware (Windows 10 with NVMe SSD).我可以让 MySQL 的 5.7 和 8.0 版本在相同的硬件(带有 NVMe SSD 的 Windows 10)上运行。 The following query is over 1000 times faster to execute under MySQL 5.7 than MySQL 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));
It takes 0.016 secs to execute on MySQL 5.7, but 19.6 secs on MySQL 8.0.在 MySQL 5.7 上执行需要 0.016 秒,但在 MySQL 8.0 上执行需要 19.6 秒。
The tables use MyISAM, and the oa_bdy table has 232,296 rows, but only 290 of those match the inner WHERE.这些表使用 MyISAM,而 oa_bdy 表有 232,296 行,但其中只有 290 行与内部 WHERE 匹配。 One difference is that 'EXPLAIN' on the query produces different results from the two versions.一个区别是查询上的“解释”从两个版本产生不同的结果。
MySQL MySQL | id ID | select_type选择类型 | table桌子 | partitions分区 | type类型 | possible_keys可能的键 | key钥匙 | key_len key_len | ref参考 | rows行 | filtered过滤 | Extra额外的 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
v5.7 v5.7 | 1 1 | SIMPLE简单的 | oa_bdy oa_bdy | (NULL) (无效的) | range范围 | shape形状 | shape形状 | 34 34 | (NULL) (无效的) | 1406 1406 | 10.00 10.00 | Using where使用哪里 |
v8.0 v8.0 | 1 1 | SIMPLE简单的 | oa_bdy oa_bdy | (NULL) (无效的) | ALL全部 | (NULL) (无效的) | (NULL) (无效的) | (NULL) (无效的) | (NULL) (无效的) | 232296 232296 | 10.00 10.00 | Using where使用哪里 |
I don't know enough about the MySQL internals to resolve this, but the performance difference is quite significant and detrimental.我对 MySQL 内部的了解不够,无法解决这个问题,但性能差异非常显着且有害。
Does anyone have any suggestions?有没有人有什么建议?
Thanks.谢谢。
Update (7-Feb-2021).更新(2021 年 2 月 7 日)。 Thanks for the comment about spatial index.感谢您对空间索引的评论。 The schema for both versions was the same (one was a copy of the other) and the schema does contain a spatial index.两个版本的架构相同(一个是另一个的副本),并且架构确实包含空间索引。
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
One problem seems to be that there is a new behaviour in MySQL 8 which will ignore the spatial index (for query optimization purposes) unless the column has a defined SRID (rather than just the individual cells).一个问题似乎是 MySQL 8 中有一种新行为,它将忽略空间索引(出于查询优化目的),除非该列具有定义的 SRID(而不仅仅是单个单元格)。 When the schema under 8.0 is changed to当 8.0 下的 schema 改为
CREATE TABLE `oa_bdy` (
`shape` geometry NOT NULL SRID 27700,
`oacode` varchar(9) NOT NULL,
`seatname` varchar(43) DEFAULT NULL,
PRIMARY KEY (`oacode`),
SPATIAL KEY `shape` (`shape`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
then the EXPLAIN under 8.0 matches that of 5.7, and the run-time under 8.0 drops to 0.391 secs, which is still 24 times slower than MySQL 5.7.那么 8.0 下的 EXPLAIN 与 5.7 匹配,8.0 下的运行时间下降到 0.391 秒,仍然比 MySQL 5.7 慢 24 倍。
Is there any way of getting the run-times under MySQL 8.0 to be similar to those of MySQL 5.7 for this sort of query?对于此类查询,是否有任何方法可以使 MySQL 8.0 下的运行时间与 MySQL 5.7 的运行时间相似?
You definitely have an index on your older database that isn't there on the newer one.您的旧数据库上肯定有一个索引,而新数据库上没有。 Due to the lack of index on the new database, the only way MySQL can satisfy your query is to compare every row in the table to your search criterion.由于新数据库缺少索引,MySQL 满足您的查询的唯一方法是将表中的每一行与您的搜索条件进行比较。 With the right index, the number of rows needing comparing is much smaller.使用正确的索引,需要比较的行数要少得多。
Do SHOW CREATE TABLE oa_bdy
on both 5.7 and 8.0, and compare them.在 5.7 和 8.0 上都执行SHOW CREATE TABLE oa_bdy
,然后比较它们。 The older one will surely mention one or more indexes.较旧的肯定会提到一个或多个索引。
You can create an index to help with the query you showed us by doing this....您可以通过这样做创建一个索引来帮助您向我们展示的查询......
CREATE SPATIAL INDEX x_oa_bdy_shape ON oa_bdy(shape);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.