你好我有一个问题。
我有一个表格,其中时间是一个索引。我的select语句如下所示:
select count(*) from sometable
where
time between @startTime and @endTime
and
st_intersects(location,@somePolygon);
此查询需要60秒才能运行。该表包含超过5000万行,所以我认为这是可以的。但现在如果我添加位置和索引查询需要90秒才能运行。为什么放慢速度?而不是加速?
//更新 您好,感谢四位反馈。
用索引解释
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra
1 | SIMPLE | q1_geo | NULL | range | ORT, Zeit | Zeit | 5 | NULL | 6454092 | 100.00 | Using index condition; Using where
且没有
id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra
1 | SIMPLE | q1_geo | NULL | range | Zeit | Zeit | 5 | NULL | 6454092 | 100.00 | Using index condition; Using where
//更新
版本:' 5.7.5-m15' Engien:MyISAM
CREATE TABLE `q1_geo` (
`ID` int(11) NOT NULL,
`ZEIT` datetime NOT NULL,
`R_ID` bigint(20) NOT NULL AUTO_INCREMENT,
`ORT` point NOT NULL,
PRIMARY KEY (`ID`,`ZEIT`,`R_ID`),
KEY `Zeit` (`ZEIT`),
KEY `Ort` (`ORT`(25))
) ENGINE=MyISAM AUTO_INCREMENT=842057641 DEFAULT CHARSET=latin1
答案 0 :(得分:2)
你在这里遇到了一个有趣的MySQL索引问题。当您在time
上使用简单索引时,您的查询会对该索引执行范围扫描,然后为该范围内的每一行计算st_intersects()
。
但是,当您在location
MySQL的查询计划程序上添加第二个地理索引时(发布您的EXPLAIN!发布您的表定义!)会执行两次索引扫描,然后索引合并。
您无法制作地理位置和普通列的复合索引。
要加快此查询,您需要了解的另一件事是您的时间标准或空间标准是否更具选择性。哪一个会将您的数据集缩小到较少的结果?那是你想要首先索引的那个。
你如何解决这个问题?如果你可以将location
geo变量划分为两个单独的列(它们可能是x和y,或lat和long),那么将时间x和y放入复合索引中,然后执行以下操作:
WHERE time >= @startTime
AND time <= @endTime
AND x >= MinX(@polygon)
AND x <= MaxX(@polygon)
AND y >= MinY(@polygon)
AND y <= MaxY(@polygon)
AND st_intersects(location, @somePolygon)
您需要在多边形参数上计算出Min和Max函数。
这个技巧的关键是允许你将一些(如果不是所有你的空间信息)放入一个普通的复合索引而不是一个独立的地理索引。