【问题标题】:Using filesort to sort by datetime column in MySQLMySQL中使用filesort按日期时间列排序
【发布时间】:2010-12-01 01:42:27
【问题描述】:

我有一张带有日期时间 (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 毫秒。有没有其他方法可以禁用文件排序?

如果我访问索引,我在 (PUBLIC, DATE) 上的索引不是唯一的。

表格定义:

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 ;

【问题讨论】:

  • 能否请您发布您的表的定义?只需运行SHOW CREATE TABLE Cars
  • 100 行需要 300 微秒?每行 3 微秒?这种表现并不烂。

标签: mysql indexing performance filesort


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    你需要在(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
    

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

    【讨论】:

    • 我在 (PUBLIC) 上有一个索引,第二个是复合索引 (PUBLIC, DATE)。我应该删除第一个吗?
    • 无论如何都应该使用第二个。您能否发布表格的定义?
    • 没问题。我添加了标签定义
    猜你喜欢
    • 2017-09-08
    • 2012-12-03
    • 2013-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 2016-08-09
    相关资源
    最近更新 更多