单/多表索引分析

索引分析

单表索引优化分析

查询category_id为1且comments大于1的情况下,views最多的arcticle_id

未建立索引前

在这里插入图片描述

type:ALL对全表进行了扫描,效率最低

possible_keys和key都为null,没有使用索引

rows为3,表示找到所需记录所要读取的行数

Extra有Using filesort未使用内部索引,需要优化

由于用到了category_id,comments,views三个列,先尝试对这三个列建立复合索引

create index idx_article_ccv on article(category_id,comments,views)

再次查找

在这里插入图片描述

type:range变成了建索给定范围的行,效率提高

possible_key:理论上用到了ccv索引,实际上用到了ccv索引

ref:NULL用到了索引的哪一行?null?索引失效

Extra:Using filesort没有用到索引,索引失效

为什么?明明建了索引,key也实际用到了索引,索引还会失效?

因为按照BTree索引的工作原理,先排序categort_id,如果遇到相同的category_id则再排序comments,如果遇到相同的comments则再排序views,当comments字段在复合索引中间时,因comments>1条件是一个范围值(所谓range),MySQL无法利用索引再对后面的views部分进行建索,即range类型查询字段后面的索引无效

删除刚才三个字段的索引,再对字段category_id和views建立索引

drop index idx_article_ccv on article
create index idx_article_cv on article(category_id,views)

在这里插入图片描述

type:ref 非唯一性索引扫描,返回匹配某个单独值的所有行,进一步优化

使用到了idx_article_cv索引

ref:索引使用到的列为常量const

Extra中没有了Using filesort

索引优化完成

两表索引优化分析

EXPLAIN SELECT * from class left join book on class.card = book.card

通过sql语句可知,class表和book表都有card字段,那么索引应该建在class表的card字段还是book表的card字段?

未建立索引前

在这里插入图片描述

type都是ALL,说明两表都是全表扫描,没有引用一个索引,

rows都是20,都查询了所有行,显然是一种效率十分低下的查询

先尝试给book表的card字段添加索引

在这里插入图片描述

这是在左连接的右边字段添加索引,可以看出,book表使用了索引,type类型变成了ref类型(非唯一性索引扫描,返回匹配某个单独值的所有行),ref为db0629数据库的class表的card字段(显示索引哪一列被使用了),Extra变成了Using index,效率较好的覆盖索引类型

删掉上面的索引再给class表的card字段添加索引

在这里插入图片描述

type为index和ALL,rows两个都为20,查找效率并没有上一个好

说明了什么?

给左连接的右边字段添加索引效果要好于给左连接的左边添加索引

为什么会这样?

这是因为左连接会把左边的表当成主表,主表中所有内容都会保存下来,最终结果中右表与左表不匹配的行会变为NULL,右表的数量要少于坐标,这样对右表建立索引就会减少索引长度,提高索引效率

同理,给右连接的左表字段添加索引要好于右连接的右表字段的索引

两表都加索引性能几乎没变,只不过其中一个ALL变成了index

三表索引优化分析

explain select * from class 
left join book on class.card = book.card
left join phone on book.card = phone.card

未建立索引前

在这里插入图片描述

type为ALL,rows都是20,使用了连接缓存(Using join buffer)

对book和phone表的card字段添加索引

在这里插入图片描述

book表和phone表的type都是ref类型,且rows变成了20,1,1查询效率提升

因此索引最好设置在需要经常查询的字段中

结论:

  • 尽可能减少join语句中NestedLoop的循环总次数;小表驱动大表
  • 优先优化NestedLoop的内层循环
  • 保证join语句中被驱动的表上的join字段都是索引字段,
  • 当无法保证被驱动表的join条件字段被索引且内存充足的情况下,可以把JoinBuffer的容量调高一些(JoinBuffer在my.ini中配置)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值