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

07-12 1197阅读

文章目录

  • 前言
  • 一、线上的慢sql 你们是怎么发现和处理的
    • 1.1 发现慢sql:
      • 1.1.1 通过开启mysql 的慢日志:
      • 1.1.2 通过Skywalking 平台:
      • 1.2 针对慢sql 你们是怎么处理的:
      • 二、你了解过索引吗
        • 2.1 索引是什么:
          • 2.1.1 索引为什么要用b+树实现,二叉树,b树不行吗
          • 2.1.2 你都知道哪些索引:
          • 2.1.3 你知道mysql 的回表吗:
          • 2.1.4 你知道mysql 的覆盖索引吗:
          • 2.1.5 当项目中遇到深分页你们怎么处理的:
          • 2.1.6 你们项目中通常都对表中的哪些字段创建索引
          • 2.1.7 你们有没有遇到过索引失效的情况,你们是怎么排查的
          • 总结

            前言

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


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

            1.1 发现慢sql:

            1.1.1 通过开启mysql 的慢日志:

            首先:慢sql 通体现在页面数据加载缓慢,接口的响应时间过长。

            其次:慢sql 是测试人员进行压测时,在预发布环境发现有些接口的响应时间超过了2s,然后对我们进行了反馈。

            然后:我们在预发布环境开启mysql 的慢日志,记录超过2s 的sql,将其存放在log 文件中:

            面试篇-Mysql-1+慢sql+索引最后:配置完成后我们重启了mysql ,然后让测试人员配合压测,从慢日志中拿到了慢sql:

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

            1.1.2 通过Skywalking 平台:

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

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

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

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

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

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

            面试篇-Mysql-1+慢sql+索引通常如果type 出现了 index 全索引树的扫描,和all 全表扫描,意为这我们需要对sql 进行优化。

            二、你了解过索引吗

            2.1 索引是什么:

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

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

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

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

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

            b 树是在二叉树的基础上进行的优化,他可以有多个分叉,以此来降低树的高度

            面试篇-Mysql-1+慢sql+索引B+Tree是在BTree基础上的一种优化,使其更适合实现外存储索引结构,InnoDB存储引擎就是用B+Tree实现其索引结构。b+ 树比b 树更有优势的地方在于:

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

              2.1.2 你都知道哪些索引:

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

              它们的区别在于:

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

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

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

                2.1.3 你知道mysql 的回表吗:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                    通常最左匹配原则体现在复合索引上,因为我们是对多个字段共同使用了一个索引树,索引树存储的节点数据也是按照 索引字段 从左到右进行建立的,此时当我们查询时,跳过了前面的字段,直接使用后面的字段进行查询,此时就有可能造成索引失效。

                    面试篇-Mysql-1+慢sql+索引范围查询,后面的列不会用到索引

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

                    在索引上的字段进行了运算:

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

                    字符串没有使用引号:

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

                    以% 开头 的查询:

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


                    总结

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

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]