为什么此查询被记录为 "not using indexes"?

Why is this query being logged as "not using indexes"?

出于某种原因,我的慢速查询日志将以下查询报告为 "not using indexes",我一直无法理解为什么。

这里是查询:

update  scheduletask
set     active = 0
where   nextrun < date_sub( now(), interval 2 minute )
and     enabled = 1
and     active = 1;

这里是 table:

CREATE TABLE `scheduletask` (
  `scheduletaskid` int(11) NOT NULL AUTO_INCREMENT,
  `schedulethreadid` int(11) NOT NULL,
  `taskname` varchar(50) NOT NULL,
  `taskpath` varchar(100) NOT NULL,
  `tasknote` text,
  `recur` int(11) NOT NULL,
  `taskinterval` int(11) NOT NULL,
  `lastrunstart` datetime NOT NULL,
  `lastruncomplete` datetime NOT NULL,
  `nextrun` datetime NOT NULL,
  `active` int(11) NOT NULL,
  `enabled` int(11) NOT NULL,
  `creatorid` int(11) NOT NULL,
  `editorid` int(11) NOT NULL,
  `created` datetime NOT NULL,
  `edited` datetime NOT NULL,
  PRIMARY KEY (`scheduletaskid`),
  UNIQUE KEY `Name` (`taskname`),
  KEY `IDX_NEXTRUN` (`nextrun`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=latin1;

尝试在 mysql 中使用 "explain" 命令。 http://dev.mysql.com/doc/refman/5.5/en/explain.html 我认为解释仅适用于 select 语句,请尝试:

解释 select * from scheduletask where nextrun < date_sub( now(), interval 2 minute ) and enabled = 1 and active = 1;

也许如果您使用 nextrun = ...,它会匹配密钥 IDX_NEXTRUN。在您的 where 子句中,必须是您的键之一、scheduletaskid、taskname 或 nextrun

抱歉,我的回答很简短,但我没有时间写完整的解决方案。

我相信您可以通过在查询中使用之前将 date_sub( now(), interval 2 minute ) 保存在一个临时变量中来解决您的问题,也许请参见此处:MySql How to set a local variable in an update statement (Syntax?)

像这样添加另一个索引

KEY `IDX_COMB` (`nextrun`, `enabled`, `active`)

我不确定您的 table 有多少行,但以下可能也适用

Sometimes MySQL does not use an index, even if one is available. One circumstance under which this occurs is when the optimizer estimates that using the index would require MySQL to access a very large percentage of the rows in the table. (In this case, a table scan is likely to be much faster because it requires fewer seeks.)