2011-05-24 84 views
1

我正在修改我的網站的內部郵件系統,並且遇到了一些我不明白的東西。下面是表:不等於Where子句使用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 

的EXPLAIN的查詢顯示「使用,其中,使用索引;使用文件排序」。但是,如果我將查詢更改爲:

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顯示「使用where;使用索引」。出於某種原因,在第一個查詢中使用!=會導致一個filesort,但在第二個查詢中使用=不會使用filesort。我很好奇發生了什麼事情會導致差異?

回答

2

等於包容,!=是排他性的。 MySQL更有效地找到包容性結果。

「使用的filesort」在這種情況下實際上是負的,因爲這意味着查詢需要使用臨時表來排序(表作爲文件),然後返回結果..

+0

我總是假設filesort是負的。我很好奇爲什麼包容性和排他性的運營商會做出這樣的改變。 – mellowsoon 2011-05-24 01:35:54

0

INDEX(recipient_idstatusdate_sent在用於排序的第二查詢時,由於第一列2是固定的,並且由順序使用第三一個date_sent =>無filesort

它不能在第一個查詢中使用,因爲status不是常量(!= 'deleted')。

更多的信息在這裏:ORDER BY Optimization