使用filesort按MySQL中的datetime列进行排序

时间:2009-09-24 12:02:46

标签: mysql indexing performance filesort

我有一张带有日期时间(DATE)和位(PUBLIC)的汽车。

现在我想采用DATE排序的行和PUBLIC = 1,所以我使用:

select
  c.*
from
  Cars c
WHERE 
   c.PUBLIC = 1
ORDER BY 
   DATE DESC

但不幸的是,当我使用解释来查看发生了什么时,我有这个:

1   SIMPLE  a   ALL     IDX_PUBLIC,DATE     NULL    NULL    NULL    103     Using where; Using filesort

当我只有100行时,需要0.3毫秒来获取这些数据。还有其他方法可以禁用filesort吗?

如果我去索引,我的索引(PUBLIC,DATE)不是唯一的。

表格def:

CREATE TABLE IF NOT EXISTS `Cars` (
  `ID` int(11) NOT NULL auto_increment,
  `DATE` datetime NOT NULL,
  `PUBLIC` binary(1) NOT NULL default '0'
  PRIMARY KEY  (`ID`),
  KEY `IDX_PUBLIC` (`PUBLIC`),
  KEY `DATE` (`PUBLIC`,`DATE`)
) ENGINE=MyISAM  AUTO_INCREMENT=186 ;

2 个答案:

答案 0 :(得分:1)

如果您按日期订购,则需要进行排序。如果按日期没有索引,则将使用filesort。摆脱这种情况的唯一方法是在日期添加索引或不按顺序执行。

此外,文件排序并不总是暗示文件将在磁盘上排序。如果表足够小或者排序缓冲区足够大,它可以在内存中对其进行排序。它只意味着表本身必须进行排序。

看起来你已经有了一个日期索引,并且由于你在where子句中使用PUBLIC,MySQL应该能够使用该索引。但是,优化器可能已经决定,因为您有这么少的行,所以不值得使用索引。尝试向表中添加10,000行,重新分析它,看看是否会改变计划。

答案 1 :(得分:1)

您需要在(public, date)

上有一个综合索引

这样,MySQL将对public进行过滤,并对date进行排序。

EXPLAIN我发现(public, date)上没有综合索引。

相反,您在publicdate上有两个不同的索引。至少,这就是他们的名字IDX_PUBLICDATE所说的。

<强>更新

public列不是BIT,而是BINARY(1)。它是一种字符类型,使用字符比较。

将整数与字符进行比较时,MySQL会将后者转换为前者,反之亦然。

这些查询会返回不同的结果:

CREATE TABLE t_binary (val BINARY(2) NOT NULL);

INSERT
INTO    t_binary
VALUES
(1),
(2),
(3),
(10);

SELECT  *
FROM    t_binary
WHERE   val <= 10;

---
1
2
3
10

SELECT  *
FROM    t_binary
WHERE   val <= '10';
---
1
10

public列更改为bit或将查询重写为:

SELECT  c.*
FROM    Cars c
WHERE   c.PUBLIC = '1'
ORDER BY 
        DATE DESC

,我。即将字符与字符进行比较,而不是整数。