MySQL 在执行“order by”时停留在“使用文件排序”上

Posted

技术标签:

【中文标题】MySQL 在执行“order by”时停留在“使用文件排序”上【英文标题】:MySQL stuck on "using filesort" when doing an "order by" 【发布时间】:2010-04-20 02:52:52 【问题描述】:

我似乎无法让我的查询停止使用文件排序。

这是我的查询:

SELECT s.`pilot`, p.`name`, s.`sector`, s.`hull` 
FROM `pilots` p 
 LEFT JOIN `ships` s ON ( (s.`game` = p.`game`) 
  AND (s.`pilot` = p.`id`) ) 
WHERE p.`game` = 1 
 AND p.`id` <> 2 
 AND s.`sector` = 43 
 AND s.`hull` > 0 
ORDER BY p.`last_move` DESC

表结构:

CREATE TABLE IF NOT EXISTS `pilots` (
  `id` mediumint(5) unsigned NOT NULL AUTO_INCREMENT,
  `game` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `last_move` int(10) NOT NULL DEFAULT '0',
  UNIQUE KEY `id` (`id`),
  KEY `last_move` (`last_move`),
  KEY `game_id_lastmove` (`game`,`id`,`last_move`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;

CREATE TABLE IF NOT EXISTS `ships` (
  `id` mediumint(5) unsigned NOT NULL AUTO_INCREMENT,
  `game` tinyint(3) unsigned NOT NULL DEFAULT '0',
  `pilot` mediumint(5) unsigned NOT NULL DEFAULT '0',
  `sector` smallint(5) unsigned NOT NULL DEFAULT '0',
  `hull` smallint(4) unsigned NOT NULL DEFAULT '50',
  UNIQUE KEY `id` (`id`),
  KEY `game` (`game`),
  KEY `pilot` (`pilot`),
  KEY `sector` (`sector`),
  KEY `hull` (`hull`),
  KEY `game_2` (`game`,`pilot`,`sector`,`hull`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;

解释:

id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra
1  SIMPLE     p  ref  id,game_id_lastmove  game_id_lastmove  1  const  7  Using where; Using filesort
1  SIMPLE     s  ref  game,pilot,sector...  game_2  6  const,fightclub_alpha.p.id,const  1    Using where; Using index

编辑:我从查询/表结构中删除了一些不必要的部分。

有人有什么想法吗?

【问题讨论】:

【参考方案1】:

你能做的最好的事情就是制作索引:

    索引覆盖表 ships 的字段:game + pilot + sector + hull按此特定顺序pilots: game + id

此特定查询将始终使用文件排序,因为它没有范围条件 p.id 2

【讨论】:

感谢您的快速答复。不知道 NOT 会强制它使用文件排序!创建索引时字段的顺序是否重要? 我刚刚尝试删除 p.id2 并且它仍然使用文件排序。 :( 删除该条件后,新索引应该出现:飞行员:game + last_move。 ps: 不强制使用文件排序 - 它只是避免使用索引的最右边部分。 pps:是的,索引中字段的顺序很重要 这似乎效果很好!我将手动从结果集中删除 p.id = 2 。谢谢【参考方案2】:

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

在某些情况下,MySQL 无法使用 用于解析 ORDER BY 的索引, 虽然它仍然使用索引来查找 匹配 WHERE 子句的行。 这些案例包括以下... 用于获取行的键不是 与订单中使用的相同 由

【讨论】:

以上是关于MySQL 在执行“order by”时停留在“使用文件排序”上的主要内容,如果未能解决你的问题,请参考以下文章

用户定义变量存在时 MySQL 中“order by”子句的执行顺序

mysql:group by,order by

如何在 MySQL 中执行 2 Order By 子句?

mysql 用 group by 和 order by同时使用

Mysql5.7中子查询时order by与group by合用无效的解决办法

坑,MySQL中 order by 与 limit 混用,分页有BUG!