当order by与where子句不同时,任何避免文件排序的方法是什么?

Jul*_*n H 10 mysql

我有一个非常简单的查询(表类型InnoDb),并EXPLAIN说MySQL必须做一个额外的传递,以找出如何按排序顺序检索行.

SELECT * FROM `comments` 
WHERE (commentable_id = 1976) 
ORDER BY created_at desc LIMIT 0, 5
Run Code Online (Sandbox Code Playgroud)

确切解释输出:

table   select_type     type    extra                          possible_keys   key             key length   ref     rows
comments   simple      ref   using where; using filesort    common_lookups  common_lookups  5   const   89
Run Code Online (Sandbox Code Playgroud)

commentable_id已编入索引.评论没有任何技巧,只是一个内容领域.

该手册表明,如果order by与where不同,则无法避免filesort.

http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

我也试过id和它的等价但是没有区别,即使我添加id作为索引(我理解这不是必需的,因为id在MySQL中隐式索引).

提前感谢任何想法!

标记 - 这是SHOW CREATE TABLE

CREATE TABLE `comments` (
  `id` int(11) NOT NULL auto_increment,
  `user_id` int(11) default NULL,
  `commentable_type` varchar(255) default NULL,
  `commentable_id` int(11) default NULL,
  `content` text,
  `created_at` datetime default NULL,
  `updated_at` datetime default NULL,
  `hidden` tinyint(1) default '0',
  `public` tinyint(1) default '1',
  `access_point` int(11) default '0',
  `item_id` int(11) default NULL,
  PRIMARY KEY  (`id`),
  KEY `created_at` (`created_at`),
  KEY `common_lookups` (`commentable_id`,`commentable_type`,`hidden`,`created_at`,`public`),
  KEY `index_comments_on_item_id` (`item_id`),
  KEY `index_comments_on_item_id_and_created_at` (`item_id`,`created_at`),
  KEY `index_comments_on_user_id` (`user_id`),
  KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=31803 DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)

Bil*_*win 5

请注意,MySQL 术语文件排序并不一定意味着它写入磁盘。这只是意味着它将在不使用索引的情况下进行排序。如果结果集足够小,MySQL 会在内存中对其进行排序,这比磁盘 I/O 快几个数量级。

您可以使用服务器变量增加 MySQL 为内存中文件排序分配的内存量sort_buffer_size。在 MySQL 5.1 中,默认排序缓冲区大小为 2MB,最大可以分配为 4GB。


更新:关于 Jonathan Leffler 关于测量排序需要多长时间的评论,您可以学习如何使用SHOW PROFILE FOR QUERY它将为您提供查询执行的每个阶段需要多长时间的详细信息。