MYSQL调优之索引——索引分析

一、单表索引

执行情况.png
发现问题:该查询typeALL,存在全表扫描问题,未使用到索引,并且存在Using filesort,文件内排序问题,需要优化。

开始优化:

1、创建复合索引

ALERT TABLE ' article' ADD INDEX index_article_ccv ('category_id','comments','views')
或者
create index  index_article_ccv on article('category_id','comments','views')

执行分析.png
分析:实际使用到了复合索引,typerange,但是仍然存在存在Using filesort,文件内排序问题。comments>1这里是范围,范围以后索引会导致失效----后面会做详细处理。
说明当前建立的索引,不合适,因为存在comments>1范围查询,导致文件内排序。

具体执行分析:

  • type为range是可以接受的,但是extra中存在Using filesort,文件内排序问题,仍是无法接受的,但是为什么我们建立的索引没啥用呢?
  • 因为我们按照Btree工作原理,先排序category_id,若果遇到相同的category_id则再排序comments,如果再遇到comments相同则排序views
  • comments字段在联合索引里处于中间位置时,因为comments>1条件是一个范围值(range),mysql无法利用索引再对后面的views部分进行检索,即range类型查询字段后面的索引无效。

解决

绕过comments索引重新建立索引,删除之前创建的索引,创建新索引,

create index  index_article_ccv on article('category_id','views')

image.png

二、两表

1、左连接

左连接.png
未使用索引的情况下为全表扫描

开始优化:
  • 右表添加索引
    右表加索引.png
    左表为索引检索,右表为全表扫描
  • 删除右表索引 , 左表添加索引
    右表加索引.png
分析得出

明显左连接右表添加索引效果要好(ref>index)。这是由于左连接的特性决定的LEF JOIN条件用于确定如何从右表搜索行,左边一定有。所以,左连接加右表。

2、右连接

因为RIGHT JOIN条件用于确定如何从左表搜索行,右边一定都有,所以左边才是关键点一定要加索引。

总结:

左连接,索引建右表;右连接索引加左表。

三、三表连接

1、三表左连接

三表左连接.png
全部为全表扫描

  • 建立索引
     建立索引.png
  • 执行结果
    执行结果.png
    后面2个type都是ref且rows优化很好,效果不错。因此索引最好设置在需要经常查询的字段中

总结:

  • 尽可能的减少join语句中的NestedLoop的循环次数:“永远小结果集驱动大结果集”——小表驱动大表
  • 优化 NestedLoop(嵌套循环)的内层循环
  • 保证join语句中被驱动表上join条件字段已被索引
  • 当无法保证被驱动表的join条件字段被索引且内存资源充足的前提下,不要吝啬joinbuffer的设置。

在这里插入图片描述

发布了41 篇原创文章 · 获赞 14 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Yunwei_Zheng/article/details/104017109