2011-05-22 38 views
5

表结构:为什么MySQL在这种情况下使用filesort?

CREATE TABLE IF NOT EXISTS `newsletters` 
(
    `id` int(11) NOT NULL auto_increment, 
    `last_update` int(11) default NULL, 
    `status` int(11) default '0', 
    `message_id` varchar(255) default NULL, 
    PRIMARY KEY (`id`), 
    KEY `status` (`status`), 
    KEY `message_id` (`message_id`), 
    KEY `last_update` (`last_update`) 
) 
ENGINE=MyISAM DEFAULT CHARSET=latin1; 

查询:

SELECT id, last_update 
FROM newsletters 
WHERE status = 1 
ORDER BY last_update DESC 
LIMIT 0, 100 
  • newsletters表有超过300万条记录
  • 查询接管26秒执行

查询说明:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE newsletters range status status 5 NULL 3043354 Using where; Using filesort 

那么为什么不使用filesort,以及它是如何一个range查询?

回答

5

它使用filesort来排序last_update。您可以通过将索引更改为status, last_update来避免这种filesort,因此MySQL会以正确的顺序查找状态为1的所有行。

要进一步优化,请将索引更改为status, last_update, id。这样MySQL就可以通过查看索引来满足查询,而无需查找表。

CREATE INDEX idx_newsletters_status 
ON newsletters(status, last_update, id); 
+0

KEY应该应用与INDEX相同的索引。 – 2011-05-22 08:17:36

+0

这样做,我是一个业余的优化/索引,所以我没有真正考虑尝试索引多个列。 @Baez:你能说说你的意思吗? – HyderA 2011-05-22 08:23:19

+1

@gAMBOOKa:为了想象什么样的索引对你最有帮助,试着想一下列表,按照什么顺序最能帮助_you_如果你是电脑,并且必须快速找到正确的记录,并返回询问信息。在这种情况下,您需要一个所有记录的列表(因为每个索引需要是所有记录)按状态排序(因为您只对1s感兴趣),然后按last_update排序(这样您可以快速获得前100名)。如果您将该ID添加到列表中,那么您可以获取所有信息而无需返回主表。 – Avi 2011-05-22 10:32:33

相关问题