MySql 8.0.11 spatial queries slow by a factor of 100000
Asked Answered
M

2

8

We have migrated a copy of a MySql 5.7 database to MySql 8.0.11 on Amazon RDS. Where possible everything is identical. A table containing geometry data has been modified so the geometry column is restricted to SRID 0 and the spatial index rebuilt. The execution plan on both databases are identical and indicate the query is using the spatial index.

On the MySql 5.7 the following query takes 0.001s on MySql 8 it takes 108s. Looking at the execution statistics ‘Sending data’ account for 100% of the time on MySql 8. Why?

SELECT r.roadid                             
FROM geocoder.osm_road r
WHERE mbrintersects(ST_Buffer(ST_GEOMETRYFROMTEXT('Point(-1.91289 52.58260)',0),0.0005), r.geometry) 

We have many different spatial queries, and all are behaving like this, but in particular MBRINTERSECTS and ST_INTERSECTS seem incredibly slow. Changing to ST_CONTAINS (where possible) makes a significant improvement (ie the above takes 3s instead of 108s), but this is not suitable for many queries and is still slower than in 5.7 by a significant margin.

Show Create Table for 5.7

CREATE TABLE `osm_road` (
  `roadid` bigint(20) NOT NULL,
  `reference` varchar(20) DEFAULT NULL,
  `name` varchar(100) DEFAULT NULL,
  `dictionary` longtext,
  `road_speed_limit` tinyint(4) unsigned NOT NULL,
  `road_speed_unitid` tinyint(1) NOT NULL,
  `road_type` tinyint(4) NOT NULL,
  `is_toll_road` bit(1) NOT NULL DEFAULT b'0',
  `is_one_way` bit(1) NOT NULL DEFAULT b'0',
  `countryid` smallint(6) DEFAULT NULL,
  `geometry` geometry NOT NULL,
  `datemodified` datetime DEFAULT CURRENT_TIMESTAMP,
  `datecreated` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`roadid`),
  UNIQUE KEY `id_roadid` (`roadid`),
  SPATIAL KEY `ix_road_geometry` (`geometry`),
  KEY `ix_road_reference` (`reference`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AVG_ROW_LENGTH=207


Show Create Table for 8.0.11

CREATE TABLE `osm_road` (
  `roadid` bigint(20) NOT NULL,
  `reference` varchar(20) DEFAULT NULL,
  `name` varchar(100) DEFAULT NULL,
  `dictionary` longtext,
  `road_speed_limit` tinyint(4) unsigned NOT NULL,
  `road_speed_unitid` tinyint(1) NOT NULL,
  `road_type` tinyint(4) NOT NULL,
  `is_toll_road` bit(1) NOT NULL DEFAULT b'0',
  `is_one_way` bit(1) NOT NULL DEFAULT b'0',
  `countryid` smallint(6) DEFAULT NULL,
  `geometry` geometry NOT NULL /*!80003 SRID 0 */,
  `datemodified` datetime DEFAULT CURRENT_TIMESTAMP,
  `datecreated` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`roadid`),
  UNIQUE KEY `id_roadid` (`roadid`),
  KEY `ix_road_reference` (`reference`),
  SPATIAL KEY `ix_road_geometry` (`geometry`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AVG_ROW_LENGTH=207

Show Index From osm_road (5.7)

Table,Non_unique,Key_name,Seq_in_index,Column_name,Collation,Cardinality,Sub_part,Packed,Null,Index_type,Comment,Index_comment
osm_road,0,PRIMARY,1,roadid,A,18973144,NULL,NULL,,BTREE,,
osm_road,1,ix_road_geometry,1,geometry,A,18973154,32,NULL,,SPATIAL,,
osm_road,1,ix_road_reference,1,reference,A,199900,NULL,NULL,YES,BTREE,,

Show Index From osm_road (8.0.11)

Table,Non_unique,Key_name,Seq_in_index,Column_name,Collation,Cardinality,Sub_part,Packed,Null,Index_type,Comment,Index_comment,Visible
osm_road,0,PRIMARY,1,roadid,A,16194921,NULL,NULL,,BTREE,,,YES
osm_road,1,ix_road_reference,1,reference,A,86215,NULL,NULL,YES,BTREE,,,YES
osm_road,1,ix_road_geometry,1,geometry,A,16194921,32,NULL,,SPATIAL,,,YES

Show Global Status (8.0.11) Click Here

Show Global Variables (8.0.11) Click Here

-- Added 2019-01-27 -----------------

EXPLAIN SELECT r.roadid FROM geocoder.osm_road r WHERE mbrintersects(ST_Buffer(ST_GEOMETRYFROMTEXT('Point(-1.91289 52.58260)',0),0.0005), r.geometry); 

Returns:

select_type:   Simple
table:         r
partitions:    null
possible_keys: ix_road_geometry
key:           ix_road_geometry
key_len:       34
ref:           null
rows:          1
filtered:      100
Extra:         Using where
Matazzoni answered 17/12, 2018 at 16:45 Comment(17)
Post SHOW CREATE TABLE <table> output for both MySQL servers. Also provide us with EXPLAIN <query> for both servers, we would like to verify..Holle
"MySql 5.7 the following query takes 0.001s'" That sounds like query cache to me or a better configured MySQL 5.7 server for the innodb buffers.. Besides the MySQL 8.0.11 server installation is new so it's "cold" running vs a long existing "warm" Server with innodb cacheHolle
Both databases were cold, none production databases. See original posting for Show Create Table informationMatazzoni
"Both databases were cold, none production databases" i wanted to be sure caching wasn't involved in this.. Can you also share the EXPLAIN's?Holle
I would also add that there are only 32,000 row within this table. See origianl now 'edited' posting for details of EXPLAINSMatazzoni
Just noticed you sure this is the correct table? you use osm_road table in the query you pasted the create structure from countryHolle
Thank you for paying closer attention than myself. Have been doing too many tests :o) This table has 16,194,921 rows. Have updated my orginal posting with the correct table detailsMatazzoni
"execution statistics ‘Sending data’ account for 100% of the time on MySql 8. Why?" -- Because that is what it always says. The statistic is useless.Frieda
Did 5.7 have the Query cache turned on, but 8.0 have it off?Frieda
A PRIMARY KEY is a UNIQUE key, so you have a redundant index on roadid.Frieda
What was the value of innodb_buffer_pool_size on each server? And the amount of RAM on each?Frieda
Query cache is ON in MySql5.7 and OFF on MySql 8. Research indicates MySQl 8 does not support query cache. I doubt this feature would be removed if it were critical too spatial queries.Matazzoni
innodb_buffer_pool_size = 12884901888 on both 5.7 & 8. Both have 16GB ram (db.t2.xlarge - 4vCPU on AWS)Matazzoni
@PhilJenson Please post SHOW INDEX FROM osm_road from your 5.7 and 8 versions. We will then see then see the facts from each table, please. From v 8 only, please post TEXT results of SHOW GLOBAL STATUS; and SHOW GLOBAL VARIABLES; for analysis.Mutazilite
Show Index Information has been added to original post. Show Global information has been added to original post as links (see very bottom). ThanksMatazzoni
@WilsonHauck. I have added EXPLAIN results to original posting. Whilst I do not wish to impose; if you email me at [email protected] I can give you access to a test database on AWS for you to see first-hand and/or skype details.Matazzoni
Hello, we have see exactly the same behavior. Some spatial functions such as MBRContains and MBRWithin do use the spatial index, but MBRIntersects doesn't (and is even slower than a full range scan). I have open a MySQL bug about this.Evangelin
C
4

MBRIntersects and ST_Intersects are broken in MySQL 8.0 (tested in 8.0.15) and are more than 10x slower compared to MySQL 5.7. For me disabling the use of the spatial index (using IGNORE INDEX, forcing a full table scan, speeds up my queries somewhat. See this bug report https://bugs.mysql.com/bug.php?id=94655

Copter answered 22/7, 2019 at 17:21 Comment(1)
This is supposed to be fixed in MySql 8.0.20. As we use AWS I wont know until AWS release this minor update, which probably will take 12 months.Matazzoni
S
0

I had similar problems and the answer was to ensure the spatial columns included a SRID. See https://mysqlserverteam.com/upgrading-to-mysql-8-0-with-spatial-data/. After doing that the queries started to use the spatial index, which they weren't doing before

Style answered 2/10, 2019 at 6:41 Comment(3)
Glad this is working for you. We have set SRID but the problem still exists on the most simple of queries. Everything points to a serious bug within MySql v8, which has been reported.Matazzoni
This fixed my issue with other spatial functions in MySQL 8, but I can’t speak to the original poster’s issue. Because this is the thread (and answer!) that helped me, let me spell it out a bit more for anyone else who comes looking. 1. If it isn’t already, change your table to InnoDB. 2. Remove any existing indexes that use the column. 3. Change the SRID of the column. (Sample syntax: ALTER TABLE myTable MODIFY COLUMN myColumn GEOMETRY SRID 4326 NOT NULL). 4. Recreate any indexes.Uchida
This is useful information which needs to be done (and has in our case). But it does not change the fact that there is a serious bug within version 8 which causes the most basic geospatial queries to run unbelievably slow on large data sets (compared with MySql 5.7 and Postgres). This has been recognized as a problem. bugs.mysql.com/bug.php?id=94655Matazzoni

© 2022 - 2024 — McMap. All rights reserved.