2011-04-13 74 views
1

好的低速選擇查詢,這裏的交易:的mysql儘管索引

我有一個可愛的小4Gb的表稱爲郵件上,我做了以下兩個查詢:

SELECT * FROM Mails WHERE sent = 1 ORDER BY date ASC LIMIT 600; // 200ms 
SELECT * FROM Mails WHERE sent = 0 ORDER BY date ASC LIMIT 600; // >9000ms 

發送類型之間的關係是以下:

0 192070 
1 1112341 
2 11992 
3 5369 

CREATE語句是這樣的:

CREATE TABLE `Mails` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `idMail` varchar(100) COLLATE utf8_bin NOT NULL, 
    `type` varchar(100) COLLATE utf8_bin DEFAULT NULL, 
    `idSender` varchar(100) COLLATE utf8_bin DEFAULT NULL, 
    `senderfName` varchar(100) COLLATE utf8_bin DEFAULT NULL, 
    `senderlName` varchar(100) COLLATE utf8_bin DEFAULT NULL, 
    `senderMail` varchar(100) COLLATE utf8_bin DEFAULT NULL, 
    `receiverMail` varchar(100) COLLATE utf8_bin DEFAULT NULL, 
    `reference` varchar(100) COLLATE utf8_bin DEFAULT NULL, 
    `mailContent` text COLLATE utf8_bin, 
    `mailSubject` varchar(100) COLLATE utf8_bin DEFAULT NULL, 
    `sent` int(1) unsigned DEFAULT '0', 
    `opened` int(1) unsigned DEFAULT '0', 
    `clicked` int(1) unsigned DEFAULT '0', 
    `completed` int(1) unsigned DEFAULT '0', 
    `abstract` varchar(100) COLLATE utf8_bin DEFAULT NULL, 
    `date` datetime DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `idMail` (`idMail`), 
    KEY `fk_type` (`type`), 
    KEY `fk_idSender` (`idSender`), 
    KEY `fk_senderMail` (`senderMail`), 
    KEY `fk_receiverMail` (`receiverMail`), 
    KEY `fk_sent` (`sent`), 
    KEY `fk_reference` (`reference`), 
    KEY `fk_date` (`date`) 
) ENGINE=MyISAM AUTO_INCREMENT=1321784 DEFAULT CHARSET=utf8 COLLATE=utf8_bin$$ 

爲什麼heck是「更重」的查詢更快或實際上在所有加載?對自我的線索:這一切都與訂購條款有關,因爲如果沒有日期排序,它們對於兩者都是閃電般的。糟糕的是,我需要那個日期嚴格排序。我不能通過id命令,因爲郵件可以生成到將來,我需要那些已經通過NOW()並且尚未發送的郵件。

[EDIT 2011-04-14]

的正確答案由AJ減速可以在下面找到。我們對這個問題的解決方案是創建一個加入索引

KEY `sent` (`sent`,`date`) 

解決絕對一切。

+1

是否發送= 0時的日期列有一堆空的? – Dave 2011-04-13 16:26:43

+0

複合'(發送,日期)'索引可能會有所幫助。正如@Dave:指出的,NULL可以通過ORDER BY查詢來殺死性能。 – 2011-04-13 16:46:53

+0

不,在日期沒有空值。 – John 2011-04-14 10:28:10

回答