MySQL在选择非索引字段时不使用索引

时间:2019-03-02 20:03:58

标签: mysql indexing

我有一个具有以下结构的表meta(这只是一个非规范化数据的示例)

`id` int(3) not null auto_increment primary key,
`category_id` int(3),
`subdomain` varchar(191),
`created_at` timestamp,
`updated_at` timestamp

subdomain字段可以存储唯一值,并且像“通用”这样的重复值可以重复多次

情况1

我也有一个索引subdomain。该索引适用于查询

Select `id` from `table` where `subdomain` = 'general'

但是当我尝试获取一些非索引字段时,mysql会扫描所有表,并且不使用索引

Select `created_at` from `table` where `subdomain` = 'general'

据我所知,Inno-db非聚集索引存储对行的引用,因此无需对所有行执行线性搜索即可检索某些字段。

我也知道优化器可以为人类选择一个意外的计划,但是在这种情况下原因可能是什么?

无论表中有多少数据,结果始终相同。

1 个答案:

答案 0 :(得分:1)

当索引支持的过滤不是选择性很差 /您要过滤的值具有高基数时,就会发生这种情况。这意味着您的总行中有很大一部分与索引支持的条件匹配(例如,您的行中有90%与subdomain = 'general'匹配)。如果在这种情况下使用索引,则与全表扫描相比,最终将处理更多数据。

示例:您有100行,其中90行与subdomain = 'general'相匹配。

全表扫描需要访问所有100行以检查条件,并读取90个值。

索引支持的select需要访问满足条件的索引中的90个项目,并按照指针从索引到实际行的顺序从该行中选择未索引的值。最终在索引上进行90次查找+从行中读取90条= 180次操作。这比全表扫描要慢,在全表扫描中,您只需要访问一些行即可。这些操作的成本可能不一样,但是最终最终您需要做更多的工作。