为啥mysql每个表只使用一个索引?

Posted

技术标签:

【中文标题】为啥mysql每个表只使用一个索引?【英文标题】:why mysql use just one index per table?为什么mysql每个表只使用一个索引? 【发布时间】:2015-04-17 19:30:19 【问题描述】:

我对我的查询运行解释,我得到了这些结果:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY bussiness   index   PRIMARY,closeBussStatus,bussStatus,approveStatus,cityID,presaleID,nameEn,DUNS,xy,subCategoryID  PRIMARY 4   NULL    295794  Using where; Using temporary; Using filesort
1   PRIMARY favourites  ref userID,bussID,userId_bussId bussID  4   haanet.bussiness.bussID 1   Using where
3   DEPENDENT SUBQUERY  rating  ref bussId  bussId  4   func    1   NULL
2   DEPENDENT SUBQUERY  rating  ref bussId  bussId  4   func    1   Using index

这表明对于第一个表有很多可能的键,但它只是选择一个索引。为什么 mysql 不为每个表使用多个索引?

【问题讨论】:

请显示相关查询。 请尽可能发布纯文本,例如SHOW CREATE TABLE 的输出,而不是小而难以辨认的屏幕截图。 @tadman 好的,我会的,一分钟! @wallyk 我已经添加了查询 您需要向我们展示表和索引定义,以及每个表的行数。也许您的表格定义不佳。也许索引没有正确创建。也许您认为您在该列上没有索引。没有看到表和索引定义,我们无法判断。我们需要行计数,因为这会影响查询计划。 【参考方案1】:

(我正在回答主题;似乎大部分细节都消失了。)

为什么只使用一个索引?这样想吧。假设您有一个包含一百万人的目录。实际上,您有两份副本,一份按名字排序,一份按姓氏排序。在一个列表中,您可以找到一千个(或多个)名字为“Rick”的条目,以及唯一的识别号。在另一个列表中,您可以找到一千个姓氏为“詹姆斯”的人,外加 id。既然你在找我,你必须以某种方式把这两个子列表放在一起来为我找到一个 id。 (以及 Superfreak 的另一个 id。)它很混乱,它涉及两个临时表,可能是某种类型的等等。

优化器认为遍历一个列表更简单,同时检查 WHERE 子句的其余部分。

但实际上(在这种情况下),“复合”索引会更好。也就是说,有一个包含一百万个名字的列表,按姓氏和名字的组合排序:INDEX(last_name, first_name)。有了它,我很容易找到。

实际上,优化器有时会按照我首先描述的方式进行操作。它称之为“索引合并交集”。 I discuss all these topics in a blog.

【讨论】:

以上是关于为啥mysql每个表只使用一个索引?的主要内容,如果未能解决你的问题,请参考以下文章

mysql索引使用的是Btree还是B+tree?为啥

MySQL - 为啥不索引每个字段?

mysql 为啥总是推荐使用联合索引而不是单值索引

MySQL-索引原理

为啥MongoDB采用B树索引,而Mysql用B+树做索引

mysql:为啥左连接不使用索引?