Mysql ORDER BY优化是否在以下SELECT语句中生效?

Mysql ORDER BY优化是否在以下SELECT语句中生效?,mysql,sql,optimization,database-indexes,Mysql,Sql,Optimization,Database Indexes,我有一个要优化的SELECT语句。报告指出,在某些情况下,索引不能用于按优化顺序。特别是这一点: 在密钥的非连续部分使用ORDER BY 从t1中选择*,其中键2=按键2的恒定顺序 让我想,这可能是事实。我使用以下索引: UNIQUE KEY `met_value_index1` (`RTU_NB`,`DATETIME`,`MP_NB`), KEY `met_value_index` (`DATETIME`,`RTU_NB`) 使用以下SQL语句: SELECT * FROM met_valu

我有一个要优化的
SELECT
语句。报告指出,在某些情况下,索引不能用于按优化
顺序。特别是这一点:

在密钥的非连续部分使用ORDER BY
从t1中选择*,其中键2=按键2的恒定顺序

让我想,这可能是事实。我使用以下索引:

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
SELECT * FROM met_value
WHERE rtu_nb=constant
AND mp_nb=constant
AND datetime BETWEEN constant AND constant
ORDER BY datetime
  • 删除索引
    met\u value\u index1
    并使用新的排序
    RTU\u NB
    MP\u NB
    DATETIME
    ,是否足够
  • 我是否必须将RTU_NB包括在<代码>订购依据<代码>条款中


结果:我尝试了@meriton的建议,并添加了索引
met\u value\u index2
选择
在1.2秒后完成,之前是在5.06秒后完成。以下内容不属于问题,但作为旁注:在进行了一些其他尝试后,我将引擎从MyISAM切换到InnoDB–使用
rtu_nb、mp_nb、datetime
作为主键–语句在0.13秒后完成

在WHERE子句中显示的字段顺序必须与索引中的顺序相匹配。因此,对于您当前的查询,您需要一个索引,其中字段的顺序为rtu_nb、mp_nb、datetime

我认为它不会对ORDER BY使用任何索引。但是你应该看看这个。或者。

我不明白你的疑问。如果一行必须匹配要返回的
mp\u np=constant
,则返回的所有行都将具有相同的
mp\u nb
,因此在order by子句中包含
mp\u nb
无效。我建议您使用语义等价的语句:

SELECT * FROM met_value
WHERE rtu_nb=constant
AND mp_nb=constant
AND datetime BETWEEN constant AND constant
ORDER BY mp_nb, datetime
SELECT * FROM met_value
WHERE rtu_nb=constant
AND mp_nb=constant
AND datetime BETWEEN constant AND constant
ORDER BY datetime
避免不必要地混淆查询优化器

现在,来回答您的问题:如果数据库知道底层访问将以正确的顺序返回行,那么它可以实现ORDERBY子句而无需排序。对于索引,这意味着如果where子句匹配的行按照ORDERBY子句请求的顺序出现在索引中,则索引可以帮助排序

这里就是这种情况,因此数据库实际上可以对
rtu\u nb=常量和常量之间的datetime
行的
met\u value\u index1
执行索引范围扫描,然后检查这些行中的每一行是否
mp\u nb=常量
,但如果
mp_nb=constant
具有很高的选择性,那么这就相当于检查了远远多于必要的行。换句话说,如果匹配行在索引中是连续的,则索引最有用,因为这意味着索引范围扫描将只接触实际需要返回的行

因此,以下索引将更有助于此查询:

UNIQUE KEY `met_value_index2` (`RTU_NB`,`MP_NB`, `DATETIME`),

由于所有匹配的行将在索引中彼此紧挨着,并且这些行在索引中的显示顺序为
orderby
子句请求的顺序。我不能说查询优化器是否足够聪明,所以您应该检查执行计划。

,而且与问题无关。在MySQL中,这是绝对正确的。innodb引擎索引尤其如此。请参阅meritons的答案或阅读Zawodnys的教科书。感谢您的解释和建议。我将尝试并尽快报告结果——目前远程机器已关机——我很好奇,会发生什么变化。