子句使用Filesort的位置不相等,但子句不相等为什么?

问题描述

| 我正在改造网站的内部邮件系统,遇到了一些我不理解的问题。表格如下:
CREATE TABLE `mails` (
    `id` bigint(12) unsigned not null auto_increment,`recipient_id` mediumint(8) unsigned not null,`date_sent` datetime not null,`status` enum(\'unread\',\'read\',\'deleted\') default \'unread\',PRIMARY KEY(`id`),INDEX(`recipient_id`,`status`,`date_sent`),CONSTRAINT FOREIGN KEY (`recipient_id`) REFERENCES `members` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB;

CREATE TABLE `mail_contents` (
    `mail_id` bigint(12) unsigned not null,`sender_id` mediumint(8) unsigned not null,`subject` varchar(150) default \'\',`content` text not null,CONSTRAINT FOREIGN KEY (`sender_id`) REFERENCES `members` (`id`) ON DELETE CASCADE,CONSTRAINT FOREIGN KEY (`mail_id`) REFERENCES `mails` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB;
这是查询
SELECT *
FROM mails AS m
LEFT JOIN mail_contents AS mc ON mc.mail_id = m.id
WHERE recipient_id = 66
AND status != \'deleted\'
ORDER BY date_sent DESC
LIMIT 40\\G
查询上的说明显示\“使用位置;使用索引;使用文件排序\”。但是,如果我将查询更改为此:
SELECT *
FROM mails AS m
LEFT JOIN mail_contents AS mc ON mc.mail_id = m.id
WHERE recipient_id = 66
AND status = \'sent\'
ORDER BY date_sent DESC
LIMIT 40\\G
EXPLAIN显示“使用位置;使用索引”。由于某种原因,在第一个查询中使用!=会导致文件排序,但是在第二个查询中使用=不会使用文件排序。我很好奇到底是什么引起了差异?     

解决方法

等于是包含的,而!=是排除的。 MySQL查找包容性结果的效率更高。 在这种情况下,“使用文件排序”实际上是负数,因为这意味着查询需要使用临时表进行排序(该表是文件),然后返回结果。     ,
INDEX(
recipient_id
status
date_sent
)在第二个查询中用于排序,因为前两列是固定的,并且排序依据是使用第三个rd5ѭ=> no
filesort
因为
status
不是常数(
!= \'deleted\'
),所以不能在第一个查询中使用它。 更多信息在这里:按优化排序