ORDERBY子句中有一个可为空的索引列会影响MySQL查询性能吗?

ORDERBY子句中有一个可为空的索引列会影响MySQL查询性能吗?,mysql,indexing,database-performance,Mysql,Indexing,Database Performance,我有一个超过一百万行的表和一个执行良好的select查询,直到我不得不更改模式,使ORDERBY子句中使用的列接受空值。该列始终被编入索引。唯一的变化是它现在允许空值 进行更改后,查询性能显著降低,导致相同流量的CPU峰值增加30倍 order by子句中只有一列。类似于orderbyid desc,其中id是一个无符号的bigint,被索引,默认为NULL 删除此列上的索引可以解决问题,但我无法理解其根本原因。我 知道会发生什么吗 在ORDERBY子句中具有可为空的索引列是否会影响 MySQL

我有一个超过一百万行的表和一个执行良好的select查询,直到我不得不更改模式,使ORDERBY子句中使用的列接受空值。该列始终被编入索引。唯一的变化是它现在允许空值

进行更改后,查询性能显著降低,导致相同流量的CPU峰值增加30倍

order by子句中只有一列。类似于
orderbyid desc
,其中id是一个无符号的bigint,被索引,默认为
NULL

删除此列上的索引可以解决问题,但我无法理解其根本原因。我

知道会发生什么吗

在ORDERBY子句中具有可为空的索引列是否会影响 MySQL查询性能如何

是的

如果可能,将列声明为不为NULL。它进行SQL操作 更快,通过更好地使用索引和消除 测试每个值是否为空。还可以节省一些存储空间, 每列一位。如果表中确实需要空值,请使用 他们。只需避免默认设置,该设置允许在每个 纵队


source

出于好奇,您的表使用什么存储引擎?MyISAM、InnoDB等…您是否知道在查询之前是否实际使用了索引/您是否有旧的执行计划?它可能未被使用,例如由于错误的统计数据(或其他查询限制),但在更改和统计数据刷新之后,MySQL(错误地)认为该索引是好的。(特别是在删除索引后,它的速度与允许null之前一样快)。或者你稍微改变了你的查询,却没有意识到这正是减慢查询速度的原因;或者允许
null
有其他一些间接影响(例如
left join
始终是隐藏的
join
现在实际上是允许
null
后的
left join
)。您如何确认这是因为可为null,而不是查询计划?如果可能的话,应该避免使用null列,但性能增益通常不会太大。@dgig-Storage engineInnoDB@Solarflare-假设基于性能变化。查询计划器使用列上的可为空的索引发布降级的性能。在这项变更之前,我没有查看规划人员,因此无法准确地归因于这项变更。因为这是唯一的变化,所以将性能下降归因于这一变化。