【问题标题】:Why does this query use an index?为什么这个查询使用索引?
【发布时间】:2012-08-23 20:40:39
【问题描述】:

我有一张包含销售信息的表格。其中一列称为royalty_currency,我需要从该表中提取所有不同的货币。这样做的查询是:

SELECT distinct `royalty_currency` FROM `sales_raw`

当我在此列上没有索引时,解释语句给我:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  sales_raw   ALL NULL    NULL    NULL    NULL    195121  Using temporary

添加索引后,解释语句给了我:

id  select_type table       type    possible_keys key              key_len  ref rows    Extra
1   SIMPLE      sales_raw   range   NULL          royalty_currency92        NULL    211 Using index for group-by

我的问题是,为什么 SELECT 语句需要使用索引?我认为索引是针对WHERE 子句的?如果只选择一列,为什么需要使用索引?最后,这是我使用的一个常见查询——我应该在royalty_currency 上的这个表中添加一个索引吗?

【问题讨论】:

  • 就像人们在下面的答案中所说的那样,索引不仅用于WHERE 子句。排序索引可用于 ORDER BY 和(在您的情况下)GROUP BY 子句。有关与GROUP BY 一起使用索引的更多信息,请参见此处:dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html

标签: mysql sql


【解决方案1】:

查询优化器似乎将您的distinct royalty_currency 要求转换为group by royalty_currency。直观地说,应该清楚两者是相同的。

group-by 使用索引是因为在该列的索引中找到具有相同 'royalty_currency' 的记录比在表本身中更有效(在索引中,这些记录都按顺序存储在叶节点中B+ 树索引的 - 假设 B+ 树索引)

为了给你更多的技术细节,我可以告诉你,B+ 树的叶子节点是在一个链表中连接的。查询引擎所做的是转到 B+ 树(索引)的最右边的叶子并开始读取每个叶子中的所有值,每次它找到一个新值时它都会返回它并忽略其余相同的值价值观。

【讨论】:

    【解决方案2】:

    索引不仅用于条件,还可以用于连接表之类的事情,在您的情况下,还可以用于分组。

    查询被解释为:

    select royalty_currency from sales_raw group by royaly_currency
    

    索引用于分组,它非常适合索引已经分组。如您所见,使用索引时引用的行数大大减少,从而使查询使用的资源少得多。

    【讨论】:

    • "查询被解释为:" --- 有关于这个的任何信息吗?尚未看到优化器将 DISTINCT 扩展为 GROUP BY 的解释
    • "Using index for group-by 与Using index table访问方法类似,Using index for group-by表示MySQL找到了一个索引,可以用来检索GROUP BY或DISTINCT的所有列无需对实际表进行任何额外磁盘访问的查询。” - 但这并不意味着查询实际上被重写为GROUP BY 表单。他们只是共享相同的额外内容
    • @zerkms:查询实际上被计划成与 SQL 查询完全不同的东西。 distinct 查询只是分组查询的一种特殊形式,查询不会被重写,它们只是以相同的方式处理。
    • 是的,他们是。这就是为什么我无法理解“查询被解释为:”的含义。查询被解释为SELECT DISTINCT
    • @Guffa 能否告诉我们用于提取查询中提到的上述记录的查询?
    【解决方案3】:

    它在那里说,正在使用GROUP BY 的索引。我知道您没有使用明确的GROUP BY,但这就是您的DISTINCT 的作用。因此,优化器认为最好使用索引(我假设该列作为他的键的一部分)来获取该列的不同值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-05
      • 1970-01-01
      • 1970-01-01
      • 2011-08-24
      • 2021-12-17
      • 2021-01-31
      • 1970-01-01
      相关资源
      最近更新 更多