面试篇-Mysql-1+慢sql+索引


前言

你们项目都使用过哪些关系型数据库,Mysql 用过吗,针对线上慢查询你们是怎么排查的,索引是什么,你们是怎么使用索引进行优化的。本文重点对面试的问题进行介绍,祝愿每位程序员都能上岸!!!


一、线上的慢sql 你们是怎么发现和处理的

1.1 发现慢sql:

1.1.1 通过开启mysql 的慢日志:

首先:慢sql 通体现在页面数据加载缓慢,接口的响应时间过长。
其次:慢sql 是测试人员进行压测时,在预发布环境发现有些接口的响应时间超过了2s,然后对我们进行了反馈。
然后:我们在预发布环境开启mysql 的慢日志,记录超过2s 的sql,将其存放在log 文件中:
在这里插入图片描述最后:配置完成后我们重启了mysql ,然后让测试人员配合压测,从慢日志中拿到了慢sql:

在这里插入图片描述

1.1.2 通过Skywalking 平台:

我们当时的系统部署了运维的监控系统Skywwalking,在展示的报表中可以看到是哪一个接口比较慢,并且可以分析这个接口哪部分比较慢,这里可以看到SOL的具体的执行时间,所以可以定位是哪个sql出了问题。
在这里插入图片描述

1.2 针对慢sql 你们是怎么处理的:

在Mysql 中提供了Explain 跟上要执行的sql ,可以看到sql 语句的执行计划,从结果中,我们主要关注sql 查询中对于索引的使用情况;

在这里插入图片描述

在结果中有个type 的字段,它是用来干嘛的,它都有哪些类型:

在这里插入图片描述通常如果type 出现了 index 全索引树的扫描,和all 全表扫描,意为这我们需要对sql 进行优化。

二、你了解过索引吗

2.1 索引是什么:

索引是一种b+ 树的数据结构,这种结构以某种方式引用数据,Myql 通过索引可以快速的定位数据。

2.1.1 索引为什么要用b+树实现,二叉树,b树不行吗

Mysql 使用b+ 树作为数据存储的底层结构,是综合了数的高度与查询效率的稳定性,综合考虑决定的。

首先,对于二叉树,二叉搜索树,红黑树来说,本质上它们都是二叉树,使用它们存储数据树的高度会变得非常大;其次二叉树在最坏的情况,会退化到链表结构,虽然红黑树可以通过左旋和右旋来维持树的平衡,但是数的总体高度依然很高,树的高度越高检索数据需要花费的时间也就越多。

在这里插入图片描述
b 树是在二叉树的基础上进行的优化,他可以有多个分叉,以此来降低树的高度
在这里插入图片描述B+Tree是在BTree基础上的一种优化,使其更适合实现外存储索引结构,InnoDB存储引擎就是用B+Tree实现其索引结构。b+ 树比b 树更有优势的地方在于:

  • 非叶子节点只存储指针,磁盘读写代价抵
  • 数据都在叶子节点查询效率稳定
  • 叶子节点双向链表,更好支持范围查询

2.1.2 你都知道哪些索引:

通常在Mysql 中,我们会用到它的聚促索引和二级索引;

它们的区别在于:
在这里插入图片描述在这里插入图片描述

你知道聚促索引的选取规则吗:

  • 如果存在主键,主键索引就是聚集索引。
  • 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。2
  • 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引。

2.1.3 你知道mysql 的回表吗:

Mysql的回表是先到二级索引中查询到id ,然后在去聚簇索引中遍历需要的id 获取到正好数据,因为有了第二次聚簇索引的遍历,所以这个过程被称之为回表。
在这里插入图片描述

2.1.4 你知道mysql 的覆盖索引吗:

覆盖索引是指查询使用了索引,返回的列,必须在索引中全部能够找到。

在这里插入图片描述

2.1.5 当项目中遇到深分页你们怎么处理的:

如sql 语句中有 limit 10000000 10 ,怎么保证sql 的效率。这种我们通查可以使用覆盖索引+子查询来处理(在子查询中得到需要的数据主键id);

在这里插入图片描述

2.1.6 你们项目中通常都对表中的哪些字段创建索引

  • 针对于数据量较大,且查询比较频繁的表建立索引。单表超过10万数据(增加用户体验)
  • 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。
  • 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。
  • 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。
  • 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。
  • 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率,
  • .如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含NULL值时,它可以更好地确定哪个索引最有效地用于查询。

你们创建索引遵循的原则有哪些;首先,我们一般在表的数据量达到10w时,会对经常作为查询条件,分组,排序的字段创建索引;然后,我们会创建覆盖索引,然后一条sql 返回的值尽量使用覆盖索引;最后,对于大文本的字段,内容较长,我们通常使用前缀索引。

  • 数据量较大,且查询比较频繁的表;
  • 常作为查询条件、排序、分组的字段
  • 字段内容区分度高
  • 内容较长,使用前缀索引
  • 尽量联合索引
  • 要控制索引的数量
  • 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它

2.1.7 你们有没有遇到过索引失效的情况,你们是怎么排查的

项目中在表的字段建立了索引,但是查询的时候却没有用到过;通常是由于违反了索引查询的一些原则,比如:没有遵守最左匹配,在查询时 % 在前面,对字段进行了运算。

说下索引的最左匹配原则:

通常最左匹配原则体现在复合索引上,因为我们是对多个字段共同使用了一个索引树,索引树存储的节点数据也是按照 索引字段 从左到右进行建立的,此时当我们查询时,跳过了前面的字段,直接使用后面的字段进行查询,此时就有可能造成索引失效。
在这里插入图片描述范围查询,后面的列不会用到索引
在这里插入图片描述
在索引上的字段进行了运算:
在这里插入图片描述
字符串没有使用引号:
在这里插入图片描述
以% 开头 的查询:
在这里插入图片描述


总结

本位对线上慢sql 的排查及优化,以及索引的一些面试问题进行总结。

  • 34
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值