八股学习(四)---MySQL

一、MySQL如何进行SQL调优?

我的回答:

面试官好!我想从SQL语句本身和数据库结构两方面来做MySQL的SQL调优。

首先会优化SQL写法,比如避免用SELECT *、减少子查询嵌套,用JOIN代替,还有合理使用索引,比如给查询频繁的字段建索引,同时避免索引失效的情况,像用函数操作索引列。

另外,会关注表结构设计,比如拆分大表、使用合适的数据类型。还会通过慢查询日志定位低效SQL,用EXPLAIN分析执行计划。我在学习中试过给查询频繁的字段加索引,查询效率确实提升了不少,这让我觉得调优能直接解决实际问题,所以也在持续积累这方面的经验,希望能更好地保证数据库性能。

回答重点官方答案:

平时进行调优,主要是观察慢SQL,然后利用explain分析查询语句的执行计划来优化查询语句。

1.合理设计索引,利用联合索引进行覆盖索引的优化,避免回表的发生,减少一次查询和随机I/0。

  1. 避免使用select *,只查询必要的字段

3.避免在SQL中进行函数计算等操作,使得无法命中索引。

4.避免使用前缀带 % 的模糊查询,导致全表扫描

5.注意联合索引需要满足最左匹配规则

6.不要对无索引字段进行排序操作

7.连表查询还要注意不同字段的字符集是否一致,否则也会导致全表扫描。

除此之外,还可以利用缓存来优化,一些变化少或者访问频繁的数据设置到缓存中,可以减轻数据库的压力,提升查询效率,还可以通过业务来优化,例如少展示一些不必要的字段,减少多表查询情况,将列表查询替换成分页分批查询等等。

若接着问explain执行计划中的各个字段

重点关注下面字段

二、如何使用MySQL的explain语句进行查询分析?

我的答案:

首先就是要在需要分析的SQL前加上explain,执行后会得到一张表,里面的字段能反映查询的关键信息,比如

看type字段,它表示连接类型,像const,eq_ref是比较好的。如果出现all就是全表扫描,就需要优化。

possible key字段是可能用到的索引。

key字段能看出实际用到的索引,如果是null就说明没走索引,此时要检查索引设计或SQL写法。

key_len是索引中使用的字节数,是索引字段最大可能长度,长度越短越好

rows字段大概估计要扫描的行数,数值越小越好。

我之前联系的时候,写了一个没有加索引的sql,用explain发现type是all,rows很大,加了索引之后,type变成ref,rows小了很多。查询速度快了很多。现在我每次写复杂sql都会先用explain分析一下,看是否有全表扫描、索引失效的情况,再针对性优化,慢慢的也更能理解索引和查询执行的关系了,以后会继续用这个工具提升SLQ效率

回答重点官方答案:

explain 主要用来 SQL 分析,它主要的属性详解如下:

  • id :查询的执行顺序的标识符,值越大优先级越高。简单查询的 id 通常为 1,复杂查询(如包含子查询或 UNION)的 id 会有多个。
  • select_type(重要):查询的类型,如 SIMPLE(简单查询)、PRIMARY(主查询)、SUBQUERY(子查询)等。
  • table :查询的数据表。
  • type(重要):访问类型,如 ALL(全表扫描)、index(索引扫描)、range(范围扫描)等。一般来说,性能从好到差的顺序是:const > eq_ref > ref > range > index > ALL。
  • possible_keys :可能用到的索引。
  • key(重要):实际用到的索引。
  • key_len :用到索引的长度。
  • ref :显示索引的哪一列被使用。
  • rows(重要):估计要扫描的行数,值越小越好。
  • filtered :显示查询条件过滤掉的行的百分比。一个高百分比表示查询条件的选择性好。
  • Extra(重要):额外信息,如 Using index(表示使用覆盖索引)、Using where(表示使用 WHERE 条件进行过滤)、Using temporary(表示使用临时表)、Using filesort(表示需要额外的排序步骤)。

type 详解:

  • system:表示查询的表只有一行(系统表)。这是一个特殊的情况,不常见。
  • const:表示查询的表最多只有一行匹配结果。这通常发生在查询条件是主键或唯一索引,并且是常量比较。
  • eq_ref:表示对于每个来自前一张表的行,MySQL 仅访问一次这个表。这通常发生在连接查询中使用主键或唯一索引的情况下。
  • ref:MySQL 使用非唯一索引扫描来查找行。查询条件使用的索引是非唯一的(如普通索引)。
  • range:表示 MySQL 会扫描表的一部分,而不是全部行。范围扫描通常出现在使用索引的范围查询中(如 BETWEEN、>,<,>=,<= )。
  • index:表示 MySQL 扫描索引中的所有行,而不是表中的所有行。即使索引列的值覆盖查询,也需要扫描整个索引。
  • all(性能最差):表示 MySQL 需要扫描表中的所有行,即全表扫描。通常出现在没有索引的查询条件中。

三、MySQL中的索引数量是否越多越好,为什么?

我的回答:

索引并不是越多越好,因为索引不论是从时间上还是空间上都是有一定成本的。

索引虽然能够加快查询速度,但会增加写操作(插入、更新、删除)的开销,每次增删改数据,不仅仅要修改表中数据,还要维护对应索引结构,索引越多,维护成本越高,可能拖慢写入性能。而且索引会占用额外的存储空间,太多的索引会浪费磁盘空间

另外查询时数据库可能会在多个索引中选择不合适的,反而影响查询效率。我之前试过给一张表加了多个索引,结果插入数据的速度明显慢了许多,所以索引要按需创建,要在查询和写入之间找平衡,所以我现在会根据实际查询场景合理建索引,避免盲目添加。

回答重点(官方答案)

索引并不是越多越好。因为索引不论从时间还是空间上都是有一定成本的

  1. 从时间上

    每次对表中的数据进行增删改 (INSERT、UPDATE 或 DELETE) 的时候,索引也必须被更新,这会增加写入操作的开销。例如删除了一个 name 为张三的记录,不仅主键索引上需要修改,如果 name 字段有索引,那么 name 索引也需要修改,所以索引越多需要修改的地方也就越多,时间开销就大了,并且 B+ 树可能会有页分裂、合并等操作,时间开销就会更大。

    还有一点需要注意:MySQL 有个查询优化器,它需要分析当前的查询,选择最优的计划,这过程就需要考虑选择哪个索引的查询成本低。如果索引过多,那么会导致优化器耗费更多的时间在选择上,甚至可能因为数据的不准确而选择了次优的索引。

  2. 从空间上

    每建立一个二级索引,都需要新建一个 B+ 树,默认每个数据页都是 16KB,如果数据量很大,索引又很多,占用的空间可不小。

相关推荐
feifeigo1233 小时前
升级到MySQL 8.4,MySQL启动报错:io_setup() failed with EAGAIN
数据库·mysql·adb
天水幼麟3 小时前
动手学深度学习-学习笔记(总)
笔记·深度学习·学习
天水幼麟5 小时前
动手学深度学习-学习笔记【二】(基础知识)
笔记·深度学习·学习
沧海一笑-dj5 小时前
【51单片机】51单片机学习笔记-课程简介
笔记·学习·51单片机·江科大·江科大学习笔记·江科大单片机·江科大51单片机
老虎06276 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
大苏打seven7 小时前
Docker学习笔记:Docker网络
笔记·学习·docker
A__tao8 小时前
一键将 SQL 转为 Java 实体类,全面支持 MySQL / PostgreSQL / Oracle!
java·sql·mysql
一只fish8 小时前
MySQL 8.0 OCP 1Z0-908 题目解析(17)
数据库·mysql
Green1Leaves8 小时前
pytorch学习-9.多分类问题
人工智能·pytorch·学习
慕y2749 小时前
Java学习第十五部分——MyBatis
java·学习·mybatis