【问题标题】:Help on MySQL table indexing when GROUP BY is used in a query在查询中使用 GROUP BY 时有关 MySQL 表索引的帮助
【发布时间】:2011-01-10 16:38:45
【问题描述】:

感谢您的关注。

有两个 INNODB 表:

作者

id        INT
nickname  VARCHAR(50) 
status    ENUM('active', 'blocked')
about     TEXT

书籍

author_id  INT
title      VARCHAR(150)

我正在对这些表进行查询,以获取每位作者和他拥有的书籍数量:

SELECT a. * , COUNT( b.id ) AS book_count
FROM authors AS a, books AS b
WHERE a.status != 'blocked'
AND b.author_id = a.id
GROUP BY a.id
ORDER BY a.nickname

此查询非常慢(执行大约需要 6 秒)。我在books.author_id 上有一个索引,它运行良好,但我不知道如何在authors 表上创建索引,以便该查询可以使用它。

这是当前 EXPLAIN 的外观:

id   select_type   table    type    possible_keys               key            key_len   ref     rows    Extra
1    SIMPLE        a        ALL     PRIMARY,id_status_nickname  NULL           NULL      NULL    3305    Using where; Using temporary; Using filesort
1    SIMPLE        b        ref     key_author_id               key_author_id  5         a.id    2       Using where; Using index

我查看了MySQL manual on optimizing queries with group by,但不知道如何将其应用于我的查询。

我将不胜感激任何帮助和提示 - 索引结构必须是什么,以便 MySQL 可以使用它?

编辑

我试过了:

(id, status, nickname)
(status, nickname)

两者都导致相同的情况。

【问题讨论】:

  • 索引的基本经验法则是,您在连接和/或 where 子句中使用的任何字段都应该被索引。对于您的查询,这意味着 a.id、b.author_id 和 a.status 都应该被编入索引。

标签: mysql indexing query-optimization


【解决方案1】:

我假设 id_status_nickname 是一个复合索引(id,status,nickname)。在您的查询中,您可以通过说 a.status != blocked 来过滤行。这有以下问题:

  1. 您没有可用于此的索引。 (id,status,nickname) 不能使用,因为 status 不是该索引的前缀
  2. 假设您有一个关于状态的索引,在使用 != 时不能使用它。您必须将其更改为 status='active'
  3. 此外,status 是一个只有两个值的枚举字段,基数会很低。所以mysql最终可能根本不使用索引。

您可以试试这个:将索引创建为 (status,id,nickname) 并使用 status='active'。我的猜测是,由于您使用 '=' 并且 status 是索引的前缀,它应该选择此索引,然后将其用于 group by 然后 order by。希望这会有所帮助。

更新: 当 WHERE 子句没有 ORDER BY 中使用的字段时,似乎无法避免文件排序。

【讨论】:

    【解决方案2】:

    我会尝试对(状态、昵称)进行索引。那应该摆脱“使用文件排序”的必要性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-02
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多