【Mysql优化】

目录

前言

1.在Mysql中,如何定位慢查询?

2.那这条SQL语句执行的很慢,如何分析(优化)呢?

3.了解过索引吗?(什么是索引?)

4.索引的底层结构了解过吗?

5.B树和B+树的区别是什么呢?

6.什么是聚簇索引,什么是非聚簇索引?(什么是聚集索引,什么是二级索引?)

7.知道什么是回表查询嘛 ?

8.知道什么叫覆盖索引嘛?

9.Mysql超大分页怎么处理?

10.索引创建原则有哪些?

11.什么情况下索引会失效?

12.谈一谈你对sql优化的经验。

总结


前言

本文主要介绍了Mysql优化相关的面试题目。


1.在Mysql中,如何定位慢查询?

参考回答:之前我们有个项目做压测的时候有的接口非常的慢,接口的响应时间超过了2秒以上,因为在MySOL中也提供了慢日志查询的功能,可以在MySOL的系统配置文件中开启这个慢日志的功能,并且也可以设置SOL执行超过多少时间来记录到一个日志文件中,所以我们设置项目配置为2秒,只要SOL执行的时间超过了2秒就会记录到日志文件中,我们就可以在日志文件找到执行比较慢的SOL了。当然,如果系统部署了运维的监控系统Skywalking等工具,可以在其展示的报表中可以看到是哪一个接口比较慢,并且可以分析这个接口哪部分比较慢,可以看到SOL的具体的执行时间,所以可以定位是哪个sql出了问题。

2.那这条SQL语句执行的很慢,如何分析(优化)呢?

可以采用MySQL自带的分析工具EXPLAIN

  • 通过key和key_len检查是否命中了索引(索引本身存在是否有失效的情况)
  • 通过type字段查看sql是否有进一步的优化空间,是否存在全索引扫描或全盘扫描
  • 通过extra建议判断,是否出现了回表的情况,如果出现了,可以尝试添加索引或修改返回字段来修复

参考回答:如果一条sql执行很慢的话,我们通常会使用mvsql自动的执行计划explain来去查看这条sql的执行情况,比如在这里面可以通过key和key_len检查是否命中了索引,如果本身已经添加了索引,也可以判断索引是否有失效的情况,第二个,可以通过type字段查看sql是否有进一步的优化空间,是否存在全索引扫描或全盘扫描,第三个可以通过extra建议来判断,是否出现了回表的情况,如果出现了,可以尝试添加索引或修改返回字段来修复。

3.了解过索引吗?(什么是索引?)

  • 索引(index)是帮助MySQL高效获取数据的数据结构(有序)。
  • 提高数据检索的效率,降低数据库的IO成本(不需要全表扫描)。
  • 通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗。

参考回答:索引在项目中还是比较常见的,它是帮助MySOL高效获取数据的数据结构,主要是用来提高数据检索的效率,降低数据库的IO成本,同时通过索引列对数据进行排序,降低数据排序的成本,也能降低了CPU的消耗。

4.索引的底层结构了解过吗?

MySQL的InnoDB擎采用的B+树的数据结构来存储索引。

  • 阶数更多,路径更短。
  • 磁盘读写代价B+树更低,非叶子节点只存储指针,叶子阶段存储数据。
  • B+树便于扫库和区间查询,叶子节点是一个双向链表。

参考回答:MySQL的默认的存储引擎lnnoDB采用的B+树的数据结构来存储索引,选择B+树的主要的原因是:第一阶数更多,路径更短,第二个磁盘读写代价B+树更低,非叶子节点只存储指针,叶子阶段存储数据,第三是B+树便于扫库和区间查询,叶子节点是一个双向链表。

5.B树和B+树的区别是什么呢?

  • 在B树中,非叶子节点和叶子节点都会存放数据,而B+树的所有的数据都会出现在叶子节点,在查询的时候,B+树查找效率更加稳定。
  • 在进行范围查询的时候,B+树效率更高,因为B+树都在叶子节点存储,并且叶子节点是一个双向链表。

6.什么是聚簇索引,什么是非聚簇索引?(什么是聚集索引,什么是二级索引?)

  • 聚簇索引(聚集索引):数据与索引放到一块,B+树的叶子节点保存了整行数据,有且只有一个。
  • 非聚簇索引(二级索引):数据与索引分开存储,B+树的叶子节点保存对应的主键,可以有多个。

聚集索引选取规则:

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

参考回答:聚簇索引主要是指数据与索引放到一块,B+树的叶子节点保存了整行数据,有且只有一个,一般情况下主键在作为聚簇索引;非聚簇索引指的是数据与索引分开存储,B+树的叶子节点保存对应的主键,可以有多个,一般我们自己定义的索引都是非聚簇索引。

7.知道什么是回表查询嘛 ?

通过二级索引找到对应的主键值,到聚集索引中查找整行数据,这个过程就是回表。

参考回答:跟刚才介绍的聚簇索引和非聚簇索引是有关系的,回表的意思就是通过二级索引找到对应的主键值,然后再通过主键值找到聚集索引中所对应的整行数据,这个过程就是回表。(如果面试官直接问回表,则需要先介绍聚簇索引和非聚簇索引)

8.知道什么叫覆盖索引嘛?

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

  • 使用id查询,直接走聚集索引查询,一次索引扫描,直接返回数据,性能高。
  • 如果返回的列中没有创建索引,有可能会触发回表查询,尽量避免使用select * 。

参考回答:覆盖索引是指select查询语句使用了索引,返回的列必须在索引中全部能够找到,如果我们使用id查询,它会直接走聚集索引查询,一次索引扫描,直接返回数据,性能高。如果按照二级索引查询数据的时候,返回的列中没有创建索引,有可能会触发回表查询,尽量避免使用select * ,尽量在返回的列中都包含添加索引的字段。

9.Mysql超大分页怎么处理?

问题:在数据量比较大时,limit分页查询,需要对数据进行排序,效率低。

解决方案:覆盖索引+子查询。

参考回答:超大分页一般都是在数据量比较大时,我们使用了limit分页查询,并且需要对数据进行排序,这个时候效率就很低,我们可以采用覆盖索引和子查询来解决。先分页查询数据的id字段,确定了id之后,再用子查询来过滤,只查询这个id列表中的数据就可以了,因为查询id的时候,走的覆盖索引,所以效率可以提升很多。

10.索引创建原则有哪些?

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

参考回答:这个情况有很多,不过都有一个大前提,就是表中的数据要超过10万以上,我们才会创建索引,并且添加索引的字段是查询比较频繁的字段,一般也是像作为查询条件,排序字段或分组的字段这些。还有就是,我们通常创建索引的时候都是使用复合索引来创建,一条sql的返回值,尽量使用覆盖索引,如果字段的区分度不高的话,我们也会把它放在组合索引后面的字段。如果某一个字段的内容较长,我们会考虑使用前缀索引来使用,当然并不是所有的字段都要添加索引,这个索引的数量也要控制,因为添加索引也会导致新增改的速度变慢。

11.什么情况下索引会失效?

  • 违反最左前缀法则。
  • 范围查询右边的列,不能使用索引。
  • 在索引列上进行运算操作,索引将失效。
  • 字符串不加单引号,造成索引失效(类型转换)。
  • 以%开头的Like模糊查询,索引失效。

参考回答:比如索引在使用的时候没有遵循最左匹配法则,第二个是模糊查询,如果%号在前面也会导致索引失效。如果在添加索引的字段上进行了运算操作或者类型转换也都会导致索引失效。如果使用了复合索引,中间使用了范围查询,右边的条件索引也会失效。所以通常情况下,想要判断出这条Sql是否有索引失效的情况,可以使用explain执行计划来分析。

12.谈一谈你对sql优化的经验。

  • 表的设计优化,数据类型的选择。
  • 索引优化,索引创建原则。
  • sql语句优化,避免索引失效,避免使用 select * 。
  • 主从复制、读写分离,不让数据的写入,影响读操作。
  • 分库分表。

参考回答:Sql优化的话,会从这几方面考虑,比如建表的时候、使用索引、Sql语句的编写、主从复制,读写分离,如果数据量比较大的话,可以考虑分库分表。创建表的时候,可以参考的阿里的开发手册,比如在定义字段的时候需要结合字段的内容来选择合适的类型,如果是数值的话,像tinyint、int、bigint这些类型,要根据实际情况选择,如果是字符串类型,也是结合存储的内容来选择char和varchar或者text类型。在使用索引的时候,可以参考索引创建原则。然后还可以对sql语句进行优化,比如SELECT语句务必指明字段名称,不要直接使用select * ;注意SOL语句避免造成索引失效的写法;如果是聚合查询,尽量用union all代替union,因为union会多一过滤,效率比较低;如果是表关联的话,尽量使用inner join ,不要使用用left join 和 right join,如必须使用一定要以小表为驱动。


总结

本文主要介绍了Mysql优化相关的面试题目。

你可能感兴趣的:(mysql,数据库)