[MDEV-28347] MyISAM spatial index is not optimal with ST_Intersects Created: 2022-04-19  Updated: 2022-08-04

Status: Open
Project: MariaDB Server
Component/s: GIS, Storage Engine - MyISAM
Affects Version/s: 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8
Fix Version/s: 10.3

Type: Bug Priority: Major
Reporter: Alexander Barkov Assignee: Alexey Botchkov
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-28348 InnoDB spatial index is not optimal w... Open

 Description   

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
 point point NOT NULL,
 SPATIAL KEY `point` (`point`)
) ENGINE=MyISAM;
 
DELIMITER $$
FOR i IN 1000..5000
DO
  INSERT INTO t1 VALUES (POINT(900, 200));
END FOR;
$$
DELIMITER ;
 
explain SELECT * FROM t1 FORCE INDEX (point) WHERE ST_Intersects(point, GeomFromText('POLYGON((3 0, 3 3, 8 3, 8 0, 3 0))'));

+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| id   | select_type | table | type  | possible_keys | key   | key_len | ref  | rows | Extra       |
+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
|    1 | SIMPLE      | t1    | range | point         | point | 34      | NULL | 4001 | Using where |
+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+

The estimation of 4001 rows does not look good. All points inserted are outside of the polygon.

ALTER TABLE t1 ENGINE=InnoDB;
explain SELECT * FROM t1 FORCE INDEX (point) WHERE ST_Intersects(point, GeomFromText('POLYGON((3 0, 3 3, 8 3, 8 0, 3 0))'));

+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| id   | select_type | table | type  | possible_keys | key   | key_len | ref  | rows | Extra       |
+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
|    1 | SIMPLE      | t1    | range | point         | point | 34      | NULL |    4 | Using where |
+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+



 Comments   
Comment by Alexander Barkov [ 2022-04-19 ]

It's also repeatable with 10.2, but needs a WHILE loop instead of FOR:

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
 point point NOT NULL,
 SPATIAL KEY `point` (`point`)
) ENGINE=MyISAM;
 
DELIMITER $$
SET @i=1000;
WHILE @i <= 5000
DO
  INSERT INTO t1 VALUES (POINT(900, 200));
  SET @i=@i+1;
END WHILE;
$$
DELIMITER ;
 
explain SELECT * FROM t1 FORCE INDEX (point) WHERE ST_Intersects(point, GeomFromText('POLYGON((3 0, 3 3, 8 3, 8 0, 3 0))'));

+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| id   | select_type | table | type  | possible_keys | key   | key_len | ref  | rows | Extra       |
+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
|    1 | SIMPLE      | t1    | range | point         | point | 34      | NULL | 4001 | Using where |
+------+-------------+-------+-------+---------------+-------+---------+------+------+-------------+

Generated at Thu Feb 08 10:00:01 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.