5

我有一个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_NBDATETIME
  • 我必须在ORDER BY子句中包含 RTU_NB 吗?


结果:我尝试了@meriton 的建议并添加了 index met_value_index2SELECT1.2 秒后完成,之前 5.06 秒后完成。以下不属于问题,但作为旁注:经过其他一些尝试,我将引擎从 MyISAM 切换到 InnoDB - 使用rtu_nb, mp_nb, datetime作为主键 - 语句在 0.13 秒后完成!

4

3 回答 3

1

我认为它不会对 ORDER BY 使用任何索引。但是你应该看看执行计划。或在这里

于 2011-12-22T17:23:35.250 回答
1

我不明白你的询问。如果一行必须匹配mp_np = constant才能返回,则所有返回的行都将具有相同的mp_nb,因此mp_nb在 order by 子句中包含无效。我建议您使用语义等效的语句:

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_index1where 的行进行索引范围扫描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子句请求的顺序出现在索引中。我不能说查询优化器是否足够聪明,所以你应该检查执行计划。

于 2011-12-22T22:37:12.153 回答
0

WHERE 子句中出现的字段顺序必须与索引中的顺序相匹配。因此,对于您当前的查询,您需要一个索引,其中的字段按 rtu_nb、mp_nb、日期时间的顺序排列。

于 2011-12-22T17:22:16.873 回答