2012-08-23 97 views
1

我有一张销售信息表。其中一列叫royalty_currency,我需要从这张表中拉出所有不同的货币。这样做的查询是:为什么此查询使用索引?

SELECT distinct `royalty_currency` FROM `sales_raw` 

当我没有在此列的索引,EXPLAIN语句给我:

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 

后,我添加一个索引,EXPLAIN语句给我:

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上的此表中添加索引?

+0

就像人们在下面的回答中所说的,索引不仅仅用于'WHERE'子句。排序索引可用于'ORDER BY'和(在你的情况下)'GROUP BY'子句。有关索引使用'GROUP BY'的更多信息,请参阅此处:http://dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html – theon

回答

1

索引不仅用于条件,它们可以用于连接表等事情,也可以用于分组。

select royalty_currency from sales_raw group by royaly_currency 

该指数是用于分组,其非常适合作为指标已经进行分组:

查询作为被解释。正如你所看到的那样,当使用索引时,引用行的数量会大大减少,从而使查询使用的资源少得多。

+0

“查询解释为:” - - 有没有关于这方面的任何信息?还没有看到优化程序将“DISTINCT”扩展为“GROUP BY”的解释 – zerkms

+0

@zerkms:解释输出显示使用分组。 – Guffa

+0

“对组使用索引 - 通过 与使用索引表访问方法类似,对group-by使用索引指示MySQL找到了一个索引,该索引可用于检索GROUP BY或DISTINCT查询的所有列,而无需任何额外的磁盘访问实际的表格。“ - 但这并不意味着查询实际上被重写为一个”GROUP BY“表单,它们只是共享相同的额外的 – zerkms

-1

它说得那么正确,使用GROUP BY的索引。我知道你没有使用明确的GROUP BY,但这就是你的DISTINCT。因此,优化器认为使用索引(我假设该列是其键的一部分)更好,以获得该列的不同值。

2

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

group-by使用索引,因为它更有效地找到在该列的索引中具有相同“royalty_currency”的记录,而不是在表中(在索引中,这些记录全部按顺序存储在叶中B +树索引的节点 - 假设B +树索引)

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