Mysql
MySQL 8 不使用空間索引?
我有一個問題,無論我做什麼我都無法讓 MySQL 使用空間索引。
像下面這樣的查詢需要 5 秒!
有什麼方法可以強制它使用索引嗎?
WITH ranked_reports AS ( SELECT station_id, raw_text, observation_time, RANK() OVER ( PARTITION BY station_id ORDER BY observation_time DESC ) order_rank FROM METAR WHERE ST_Distance_Sphere ( geo_point, ST_GeomFromText ( 'POINT(51.85 -0.79)', 4326 )) <= 100 * 1609.34 ) SELECT * FROM ranked_reports WHERE order_rank =1
查詢說明
+----+-------------+------------+------------+------+---------------+-------------+---------+-------+--------+----------+-----------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+------+---------------+-------------+---------+-------+--------+----------+-----------------------------+ | 1 | PRIMARY | <derived2> | NULL | ref | <auto_key0> | <auto_key0> | 8 | const | 10 | 100.00 | NULL | | 2 | DERIVED | METAR | NULL | ALL | NULL | NULL | NULL | NULL | 585814 | 100.00 | Using where; Using filesort | +----+-------------+------------+------------+------+---------------+-------------+---------+-------+--------+----------+-----------------------------+
表結構
CREATE TABLE `METAR` ( `station_id` varchar(5) NOT NULL, `station_iata` varchar(5) DEFAULT NULL, `observation_time` datetime NOT NULL, `latitude` float(255,2) DEFAULT NULL, `longitude` float(255,2) DEFAULT NULL, `raw_text` varchar(255) DEFAULT NULL, `temp_c` float(255,1) DEFAULT NULL, `dewpoint_c` float(255,1) DEFAULT NULL, `wind_dir_degrees` int(255) DEFAULT NULL, `wind_speed_kt` int(11) DEFAULT NULL, `wind_gust_kt` int(11) DEFAULT NULL, `visibility_statute_mi` float(255,2) DEFAULT NULL, `altim_in_hg` float(255,2) DEFAULT NULL, `altim_in_hPa` float(255,0) DEFAULT NULL, `sea_level_pressure_mb` float(255,0) DEFAULT NULL, `wx_string` varchar(255) DEFAULT NULL, `sky_condition` mediumtext, `flight_category` varchar(255) DEFAULT NULL, `three_hr_pressure_tendency_mb` float DEFAULT NULL, `maxT_c` float(255,0) DEFAULT NULL, `minT_c` float(255,0) DEFAULT NULL, `maxT24hr_c` float DEFAULT NULL, `minT24hr_c` float(255,0) DEFAULT NULL, `precip_in` float(255,0) DEFAULT NULL, `pcp3hr_in` float(255,0) DEFAULT NULL, `pcp6hr_in` float(255,0) DEFAULT NULL, `pcp24hr_in` float(255,0) DEFAULT NULL, `snow_in` float(255,0) DEFAULT NULL, `vert_vis_ft` int(255) DEFAULT NULL, `time_added` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `geo_point` point NOT NULL /*!80003 SRID 4326 */, PRIMARY KEY (`station_id`,`observation_time`), KEY `IDX_Station` (`station_id`) USING BTREE, KEY `IDX_Deletion` (`observation_time`) USING BTREE, KEY `IDX_IATA` (`station_iata`,`observation_time`) USING BTREE, SPATIAL KEY `IDX_Spatial` (`geo_point`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
您的查詢有
WHERE ST_Distance_Sphere ( geo_point, ST_GeomFromText ( 'POINT(51.85 -0.79)', 4326 )) <= 100 * 1609.34 )
在 MySQL 中,您必須使用MBR函式才能使用索引。
所以不要
ST_Distance_Sphere
改用,MBRContains( ST_Buffer( ST_SRID(POINT(51.85 -0.79), 4326), 100 * 1609.34), geog )
您需要將 SRID 添加到列定義:
SRID 屬性使空間列 SRID 受限,這具有以下含義:
該列只能包含具有給定 SRID 的值。嘗試插入具有不同 SRID 的值會產生錯誤。
優化器可以在列上使用空間索引。請參閱第 8.3.3 節,“空間索引優化”。
沒有 SRID 屬性的空間列不受 SRID 限制,並接受具有任何 SRID 的值。但是,在修改列定義以包含 SRID 屬性之前,優化器不能對它們使用 SPATIAL 索引,這可能需要首先修改列內容,以便所有值都具有相同的 SRID。