我有一个SELECT
语句,我想优化。 mysql - order by optimization表示在某些情况下,索引不能用于优化ORDER BY
。具体来说:
您在键的非连续部分使用ORDER BY SELECT * FROM t1 WHERE key2 = constant ORDER BY key_part2;
让我思考,情况可能如此。我正在使用以下索引:
UNIQUE KEY `met_value_index1` (`RTU_NB`,`DATETIME`,`MP_NB`),
KEY `met_value_index` (`DATETIME`,`RTU_NB`)
使用以下SQL语句:
SELECT * FROM met_value
WHERE rtu_nb=constant
AND mp_nb=constant
AND datetime BETWEEN constant AND constant
ORDER BY mp_nb, datetime
met_value_index1
并使用新订单RTU_NB
,MP_NB
,DATETIME
创建它?ORDER BY
子句中?<小时/> 结果:我已经尝试了@meriton的建议并添加了索引
met_value_index2
。 SELECT
在1.2秒后完成,之前在5.06秒后完成。以下不属于问题,但作为旁注:经过一些其他尝试后,我将引擎从MyISAM切换到InnoDB - 以rtu_nb, mp_nb, datetime
为主键 - 语句在0.13秒后完成!< / p>
答案 0 :(得分:1)
我认为它不会使用ORDER BY的任何索引。但你应该看看execution plan。或here。
答案 1 :(得分:1)
我没有收到您的查询。如果行必须与要返回的mp_np = constant
匹配,则返回的所有行将具有相同的mp_nb
,因此在order by子句中包含mp_nb
无效。我建议你使用语义等价的语句:
SELECT * FROM met_value
WHERE rtu_nb=constant
AND mp_nb=constant
AND datetime BETWEEN constant AND constant
ORDER BY datetime
避免不必要地混淆查询优化器。
现在,针对您的问题:如果数据库知道底层访问将以正确的顺序返回行,则数据库可以实现order by子句而不进行排序。对于索引,这意味着索引可以帮助排序,如果where子句匹配的行按order by子句请求的顺序出现在索引中。
这就是这种情况,因此对于met_value_index1
的行,数据库实际上可以对rtu_nb=constant AND datetime BETWEEN constant AND constant
进行索引范围扫描,然后检查每个行的mp_nb=constant
是否为mp_nb=constant
,但如果UNIQUE KEY `met_value_index2` (`RTU_NB`,`MP_NB`, `DATETIME`),
具有高选择性,则相当于检查远远超过必要的行数。换句话说,如果匹配的行在索引中是连续的,则索引最有用,因为这意味着索引范围扫描将仅触及实际需要返回的行。
因此,以下索引对此查询更有帮助:
order by
因为所有匹配的行将在索引中彼此相邻,并且行按照{{1}}子句请求的顺序出现在索引中。我不能说查询优化器是否足够智能,所以你应该检查执行计划。
答案 2 :(得分:0)
WHERE子句中出现的字段顺序必须与索引中的顺序匹配。因此,对于当前查询,您需要一个索引,其字段的顺序为rtu_nb,mp_nb,datetime。