MySQL避免内部查询中的文件排序

Posted

技术标签:

【中文标题】MySQL避免内部查询中的文件排序【英文标题】:MySQL avoid filesort in inner query 【发布时间】:2011-09-17 12:54:24 【问题描述】:

我试图避免文件排序,但没有从内部查询中删除它。如果我将条件移动到外部查询,那么它什么也不会显示。

Create table articles (
   article_id Int UNSIGNED NOT NULL AUTO_INCREMENT,
   editor_id Int UNSIGNED NOT NULL,
   published_date Datetime,
Primary Key (book_id)) ENGINE = InnoDB;

Create Index published_date_INX ON articles (published_date);
Create Index editor_id_INX ON articles (editor_id);

EXPLAIN SELECT article_id, article_date FROM articles AA INNER JOIN 
    (
        SELECT article_id 
          FROM articles 
         WHERE editor_id=1 
         ORDER BY published_date DESC 
         LIMIT 100, 5
    ) ART USING (article_id);

+----+-------------+------------+--------+---------------+-----------+---------+----------------+--------+----------------+
| id | select_type | table      | type   | possible_keys | key       | key_len | ref            | rows   | Extra          |
+----+-------------+------------+--------+---------------+-----------+---------+----------------+--------+----------------+
|  1 |  | PRIMARY     | <derived2> | ALL    | NULL          | NULL      | NULL   NULL           |      5 |                | 
|  1 |  | PRIMARY     | AA         | eq_ref | PRIMARY       | PRIMARY   | 4      ART.article_id |      1 |                | 
|  2 |  | DERIVED     | articles   | ALL    | editor_id     | editor_id | 5                     | 114311 | Using filesort | 
+----+-------------+------------+--------+---------------+-----------+---------+----------------+--------+----------------+

3 rows in set (30.31 sec)

有什么建议可以从这个查询中删除文件排序吗?

【问题讨论】:

【参考方案1】:

也许您可以尝试在editor_id, published_date 上添加索引。

create index edpub_INX on articles (editor_id, published_date);

关于你的内心查询:

SELECT article_id 
  FROM articles 
 WHERE editor_id=1 
 ORDER BY published_date DESC 
 LIMIT 100, 5

mysql 的查询规划器可能认为通过editor_id 过滤(使用索引)然后通过published_date 排序比使用published_date_INX 然后通过editor_id 过滤要好。查询规划器可能是对的。

因此,如果您想“帮助”该特定查询,请在 editor_id, published_date 上创建一个索引,看看它是否有助于您的查询运行得更快。

【讨论】:

edpub_INX 索引可能无助于 MySQLpublished_date 进行 sort,因为在 B+TREE 索引上,顺序很重要,而您索引键是:首先是editor_id,然后是published_date。为了帮助order by 子句,我认为查询计划器需要一个索引,其中published_date 是它的第一个字段。

以上是关于MySQL避免内部查询中的文件排序的主要内容,如果未能解决你的问题,请参考以下文章

MySQL/MariaDB - 按内部子查询排序

mysql 使用内部连接优化查询,其中和排序依据和坐标

如何避免这个mysql查询的文件排序

MySQL - 加速查询避免文件排序和临时

在 MySQL 查询中使用 OR 时,有没有办法使用索引来避免文件排序?

如何设计索引/查询以避免在简单的 MySQL 查询中进行文件排序?