我在一个(x double, y double, z double)表中有大约100亿行坐标为MySQL的点。我已经在x、y和z列上创建了索引索引,这样按范围进行筛选就很好了。
查询模板:( {}中的内容被实际值替换)
select id from points_table where
x between {x-5} and {x+5} and
y between {y-5} and {y+5} and
z between {z-5} and {z+5};奇怪的是,尽管返回的结果数量大致相同,但奇怪的是,尽管返回的结果数量大致相同,但这个查询始终占用某些点的~0.05秒,而对于另一些点则花费了极大的~1.5秒。
其中一个例子是,
对于(x,y,z) = (1,5,-6)查询,需要~0.04秒,并获取45个结果,但是,
对于(x,y,z) = (-2,0,3)查询,需要~1.20秒,并获取38个结果
这对我来说很奇怪。这种行为的原因是什么?
编辑:根据要求,这里对这两个查询进行了解释,
explain select id from points_table where x between 1-5 and 1+5 and y between 5-5 and 5+5 and z between -6-5 and -6+5;
+----+-------------+--------------+-------+-------------------+-------+---------+------+-------+-----------------------------------------------+
| id | select_type | tab | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+-------+-------------------+-------+---------+------+-------+-----------------------------------------------+
| 1 | SIMPLE | points_table | range | pnt_x,pnt_y,pnt_z | pnt_y | 9 | NULL | 18748 | Using index condition; Using where; Using MRR |
+----+-------------+--------------+-------+-------------------+-------+---------+------+-------+-----------------------------------------------+
explain select id from points_table where x between -2-5 and -2+5 and y between 0-5 and 0+5 and z between 3-5 and 3+5;
+----+-------------+--------------+-------+-------------------+-------+---------+------+--------+-----------------------------------------------+
| id | select_type | tab | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+-------+-------------------+-------+---------+------+--------+-----------------------------------------------+
| 1 | SIMPLE | points_table | range | pnt_x,pnt_y,pnt_z | pnt_y | 9 | NULL | 235748 | Using index condition; Using where; Using MRR |
+----+-------------+--------------+-------+-------------------+-------+---------+------+--------+-----------------------------------------------+我认为只使用用于y的索引,而且行数也有很大差异,这将解释时间间隔。
但现在我的问题是,
如何让mysql使用所有索引?他们在那里是有原因的。
编辑:
因此,我创建了一个复合键(x、y、z),MySQL在执行范围筛选时似乎更喜欢它,而且查询所花费的时间也一直较少。
发布于 2014-11-03 08:02:10
查询计划将告诉您实际使用的是哪个索引--但是为了讨论的目的,让我们假设Y总是被使用的。
您可能会看到类似这样的情况:索引X选择18,748行,X和Z范围过滤除45行以外的所有行,但是对于第二个查询索引X选择235,748行,X和Z范围将结果过滤为38行。
相同的查询、相同的执行计划(不包括I/O数量),但在第二个查询中处理了更多的数据,以获得在总行方面类似的结果。
按照zerkms的建议,用实际的查询计划信息更新这个答案。
https://stackoverflow.com/questions/26709681
复制相似问题