我正在尝试创建一个select查询,但是当我使用explain query时,mysql总是在额外使用“using filesort”。
我尝试使用最简单的查询,但问题并没有消失。 我的表'Partidas'的结构是:
CREATE TABLE IF NOT EXISTS `Partidas` (
`IdUsuario` int(11) NOT NULL,
`IdPartida` int(11) NOT NULL,
`TipoPartida` tinyint(4) NOT NULL,
`Facil` tinyint(1) NOT NULL DEFAULT '0',
`Normal` tinyint(1) NOT NULL DEFAULT '0',
`Dificil` tinyint(1) NOT NULL DEFAULT '0',
`FchPartida` date NOT NULL,
`PuntosPartida` mediumint(9) NOT NULL,
`IdPartidaTemp` bigint(20) NOT NULL,
`ComplPers` tinyint(1) NOT NULL,
`SoloMulti` tinyint(2) NOT NULL,
PRIMARY KEY (`IdUsuario`,`IdPartida`),
KEY `IX_PARTIDAS_RECORDS` (`TipoPartida`,`FchPartida`,`PuntosPartida`),
KEY `IX_PARTIDAS_ORDEN2` (`FchPartida`),
KEY `IX_PARTIDAS_COMPLPERS` (`ComplPers`,`FchPartida`,`PuntosPartida`),
KEY `IX_PARTIDAS_SOLOMULTI` (`SoloMulti`,`FchPartida`,`PuntosPartida`),
KEY `IX_PARTIDAS_DIFICULTAD` (`Facil`,`Normal`,`Dificil`,`SoloMulti`,`FchPartida`,`PuntosPartida`),
KEY `IX_PARTIDAS_COMPMULTI` (`ComplPers`,`SoloMulti`,`FchPartida`,`PuntosPartida`),
KEY `IX_PARTIDAS_COMPLPERS_SIMPLE` (`ComplPers`,`PuntosPartida`),
KEY `IX_PARTIDAS_SOLOMULTI_SIMPLE` (`SoloMulti`,`PuntosPartida`),
KEY `IX_PARTIDAS_FECHA` (`FchPartida`),
KEY `IX_PARTIDAS_PUNTOS` (`PuntosPartida`),
KEY `PRUEBA_PARTIDAS` (`PuntosPartida`,`TipoPartida`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
该表有大约1000-5000行(实际上是很少的数据),但始终使用filesort。我用于测试的查询是:
explain select *
from Partidas
order by PuntosPartida
limit 0, 50;
结果是:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
| 1 | SIMPLE | Partidas | ALL | NULL | NULL | NULL |NULL | 1041 | Using filesort |
但是如果在查询中我更改了限制,例如,限制0,5;那么结果也会改变
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
| 1 | SIMPLE | Partidas | index | NULL | IX_PARTIDAS_PUNTOS | 3 |NULL | 5 | |
在mysql配置中,缓冲区和排序的变量是:
-myisam sort buffer size: 2MB
-sort buffer size: 2MB
-key buffer size: 1GB
但我尝试更改这些值(将其增加到8MB)并且结果相同
感谢您的帮助
答案 0 :(得分:0)
我的猜测是这是查询优化器正在完成它的工作。 This article here显示“优化器首选全表扫描,甚至不考虑将索引扫描为相关选项(possible_keys:NULL)”
您可以强制它使用索引但执行时间可能较慢(如文章中所述)。
select *
from Partidas FORCE INDEX(IX_PARTIDAS_PUNTOS)
order by PuntosPartida
limit 0, 50;
您还可以read more here了解如何避免表扫描(“使用filesort”)