正文
作为后端开发,日常操作数据库最常用的是写操作和读操作。读操作我们下边会讲,这个分类里我们主要来看看写操作时为什么会导致 SQL 变慢。
刷脏页
脏页的定义是这样的:内存数据页和磁盘数据页不一致时,那么称这个内存数据页为脏页。
那为什么会出现脏页,刷脏页又怎么会导致 SQL 变慢呢就需要我们来看看写操作时的流程是什么样的。
对于一条写操作的 SQL 来说,执行的过程中涉及到写日志,内存及同步磁盘这几种情况。
通过在命令行执行图中的语句,可以查看当前运行的事务情况,这里介绍几个查询结果中重要的参数:
- 开启慢查询日志(临时):
注意这里只是临时开启了慢查询日志,如果 mysql 重启后则会失效。可以 my.cnf 中进行配置使其永久生效。
存在原因
知道了如何查看执行慢的 SQL 了,那么我们接着看读操作时为什么会导致慢查询。
(1)未命中索引
SQL 查询慢的原因之一是可能未命中索引,关于使用索引为什么能使查询变快以及使用时的注意事项, 上已经很多了,这里就不多赘述了。
(2)脏页问题
另一种还是我们上边所提到的刷脏页情况,只不过和写操作不同的是,是在读时候进行刷脏页的。
是不是有点懵逼,别急,听我娓娓道来:
为了避免每次在读写数据时访问磁盘增加 IO 开销,Innodb 存储引擎通过把相应的数据页和索引页加载到内存的缓冲池(buffer pool)中来提高读写速度。然后按照最近最少使用原则来保留缓冲池中的缓存数据。
那么当要读入的数据页不在内存中时,就需要到缓冲池中申请一个数据页,但缓冲池中数据页是一定的,当数据页达到上限时此时就需要把最久不使用的数据页从内存中淘汰掉。但如果淘汰的是脏页呢,那么就需要把脏页刷到磁盘里才能进行复用。
你看,又回到了刷脏页的情况,读操作时变慢你也能理解了吧/p>
防患于未然
知道了原因,我们如何来避免或缓解这种情况呢/p>
首先来看未命中索引的情况:
不知道大家有没有使用 Mysql 中 explain 的习惯,反正我是每次都会用它来查看下当前 SQL 命中索引的情况。避免其带来一些未知的隐患。
这里简单介绍下其使用方式,通过在所执行的 SQL 前加上 explain 就可以来分析当前 SQL 的执行计划:
这里需要重点关注以下几个字段:
1、type
表示 MySQL 在表中找到所需行的方式。其中常用的类型有:ALL、index、range、 ref、eq_ref、const、system、NULL 这些类型从左到右,性能逐渐变好。
-
ALL:Mysql 遍历全表来找到匹配的行;
-
index:与 ALL 区别为 index 类型只遍历索引树;
-
range:只检索给定范围的行,使用一个索引来选择行;
-
ref:表示上述表的连接匹配条件,哪些列或常量被用于查找索引列上的值;
-
eq_ref:类似ref,区别在于使用的是否为唯一索引。对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用 primary key 或者 unique key作为关联条件;
-
const、system:当 Mysql 对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于 where 列表中,Mysql 就能将该查询转换为一个常量,system 是 const类型的特例,当查询的表只有一行的情况下,使用system;
-
NULL:Mysql 在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。
2、possible_keys
查询时可能使用到的索引(但不一定会被使用,没有任何索引时显示为 NULL)。
3、key
实际使用到的索引。
4、rows
估算查找到对应的记录所需要的行数。
5、Extra
比较常见的是下面几种:
-
Useing index:表明使用了覆盖索引,无需进行回表;
-
Using where:不用读取表中所有信息,仅通过索引就可以获取所需数据,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤;
-
Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询,常见 group by,order by;
-
Using filesort:当Query中包含 order by 操作,而且无法利用索引完成的排序操作称为“文件排序”。
对于刷脏页的情况,我们需要控制脏页的比例,不要让它经常接近 75%。同时还要控制 redo log 的写盘速度,并且通过设置 innodb_io_capacity 参数告诉 InnoDB 你的磁盘能力。
最后
最后,强调几点:
- 1. 一定要谨慎对待写在简历上的东西,一定要对简历上的东西非常熟悉。因为一般情况下,面试官都是会根据你的简历来问的; 能有一个上得了台面的项目也非常重要,这很可能是面试官会大量发问的地方,所以在面试之前好好回顾一下自己所做的项目;
- 2. 和面试官聊基础知识比如设计模式的使用、多线程的使用等等,可以结合具体的项目场景或者是自己在平时是如何使用的;
- 3. 注意自己开源的Github项目,面试官可能会挖你的Github项目提问;
我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!
以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目。
如何获取整理好的Java面试专题资料/strong>
资料获取方式:点击这里免费下载
面试答案
资料*
资料获取方式:点击这里免费下载
面试答案
[外链图片转存中…(img-ZdMcXP1O-1627089075503)]
[外链图片转存中…(img-SG393z98-1627089075504)]

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91268 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!