电话:13485538018
关闭
您当前的位置:首页 > 职场资讯 > 面试秘籍

面试必问:如何定位并分析慢SQL语句

来源:网络整理 时间:2026-04-23 作者:佚名 浏览量:

面试官:MySQL中,如何定位慢查询?

候选人:

当时我们进行压测时,存在一些接口速度极为迟缓,这些接口的响应时间超出了两秒,由于那时我们的系统配备了运维监控系统Skywalking ,在呈现的报表里能够知晓是哪个接口较为缓慢,而且能够剖析该接口哪一部分较为迟缓,在此处能够看到SQL的具体执行时间,因而能够确定是哪个sql出现了问题。

要是,项目里头不存在这般运维的监控系统,实际上在MySQL当中也给出了慢日志查询的作用,能够在MySQL的系统配置文件里开启此慢日志的功能,而且还能够设定SQL执行超出多久去记录到一个日志文件内,我记得前一个项目配置的是2秒,只要SQL执行的时长超过了2秒就会被记录到日志文件之中,我们就能在日志文件那里找到执行相较缓慢的SQL了。

面试官:那这个SQL语句执行很慢, 如何分析呢?

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

若有一条 sql 执行得极为缓慢,我们一般會借此利用 mysql 自动生成的执行计划 explain 来查看该 sql 的执行状况。比如说,于其中能够凭借 key 以及 key_len 去核查有无索引被命中。要是自身已然添加了索引,同样能够判定索引是否存在失效情形。

第二个,能够借助type字段去查看sql是不是有着进一步可优化的空间,是不是存在全索引扫描这种情况或者全盘扫描的状况;第三个呢,可以依据extra建议来进行判断,是不是出现了回表的情形,要是出现了这种情况,能够尝试去添加索引或者对返回字段作出修改来将其修复。

面试官:了解过索引吗?(什么是索引)

在候选人看来,索引于项目里是较为常见的,它属于那种助力MySQL高效获取数据的数据结构,其主要作用在于提升数据检索的效率,借此降低数据库的IO成本,并且通过索引列来对数据予以排序,进而降低数据排序的成本,与此同时,还能够降低CPU的消耗。

面试官:索引的底层数据结构了解过嘛 ?

候选人:MySQL默认存储引擎InnoDB采用B+树数据结构存储索引,选择B+树主要原因如下,其一阶数更多路径更短,其二磁盘读写代价B+树更低,非叶子节点仅存储指针,叶子阶段存储数据,其三B+树便于扫库及区间查询,叶子节点为双向链表。

面试官:B树和B+树的区别是什么呢?

候选人:其一,于B树里,非叶子节点以及叶子节点全都会放置数据,然而B+树的全部数据均会现身于叶子节点,在进行查询之际,B+树的查找效率更为稳定。

第二点是,当开展范围查询之际,B + 树的效率要更高些,原因在于B + 树全都在叶子节点里进行存储,而且叶子节点属于一个双向链表。

面试官:什么是聚簇索引什么是非聚簇索引 ?

候选人:

嗯嗯~,聚簇索引主要是讲数据跟索引放置到一块儿,B+树的叶子节点保存着完整的一行数据,存在且仅存在一个,一般情形下主键是作为聚簇索引的。

非聚簇索引的值,是数据与索引分开进行存储的,B+树的叶子节点,保存着对应的主键,其可以存有多个,一般作为我们自己所定义的索引,都是非聚簇索引。

面试官:知道什么是回表查询嘛 ?

嗯,候选人表示当前所说内容,与之前介绍的聚簇索引以及非聚簇索引存有一定关联,回表的含义是借助二级索引找出对应的主键值,之后凭借主键值寻得聚集索引里所对应的整行数据,这一过程即为回表。

提请注意,要是面试官径直询问回表,那么就得先对聚簇索引予以介绍,接着还要介绍非聚簇索引。

面试官:知道什么叫覆盖索引嘛 ?

候选人:嗯~,清楚的

有着这样一种情况,覆盖索引所指的是涉及select查询语句之时使用了索引,在返回的列当中,存在这样的要求,那就是必须在索引里全部能够被找到,要是我们运用id进行查询,它会直接去走聚集索引查询,经历一次索引扫描,然后能够直接返回数据,这所呈现出的性能是比较高的。

要是依照二级索引去查询数据之际,所返回的列当中并未创建索引,极有可能会引发回表查询,最好尽力规避运用select *,尽可能在返回的列里全都涵盖添加索引的字段。

面试官:MYSQL超大分页怎么处理 ?

嗯,当数据量相对较大之际,我们运用了limit分页查询,而且还得对数据予以排序,此时效率极低,针对这种情况,我们能够借助覆盖索引以及子查询来加以解决,这就是候选人所述内容。

首先通过分页方式对数据进行查询,查询的是其中的id字段,在确定了该id之后,接着运用子查询来实施过滤操作,使之仅查询处于这个id所形成的列表范围之内的数据便可。

因为查询id的时候,走的覆盖索引,所以效率可以提升很多

面试官:索引创建原则有哪些?

候选人表示,存在诸多情况,然而存在一个大前提,即表中的数据数量要超过10万,在此条件下,才会去创建索引,而且添加索引的字段是查询较为频繁的字段,通常是用作查询条件、排序字段或者分组的字段这种情况。

此外,我们平常在创建索引之际,皆是运用复合索引去创建,对于一条sql的返回值而言,要尽可能运用覆盖索引,要是字段的区分度不够高的话,我们同样会将其置于组合索引后边的字段。

要是某一个具备了较长内容的字段,们会对使用前缀索引来予以考虑并去使用,当然,并非是所有的字段都得把索引给添加起来,对于这个索引的数量也是需要去进行控制的,因为添加索引这一行为同样会致使新增改的速度变缓慢下来。

面试官:什么情况下索引会失效 ?

情况较多,我要讲一些自己以前所遇到过的自身经验 ,我是候选人 ,嗯。

比如,索引于使用期间未依循最左匹配法则,再一个是,模糊查询,倘若%号居前同样会致使索引失效。要是于添加索引的字段之处开展了运算操作或者类型转换也均会致使索引失效。

之前我们就曾遇到过这样一种情况,那就是,倘若使用了复合索引,其中间运用了范围查询,那么右边条件索引也会失效。

正常状况时,所以,若要判断这条sql有与否索引失效状况,能够运用explain执行计划予以剖析,一般情况下。

面试官:sql的优化的经验

对于候选人而言,嗯,在项目当中这的确是比较常见的情况,当然了,如果直接提及sql优化这一事项的话,我们会从以下几方面去进行考虑,比如说。

进行建表操作时,要关于使用索引,要涉及sql语句的编写,要处理主从复制,要实现读写分离,另外要是量相对大些的话,能够去考虑分库分表。

MySQL慢查询定位_MySQL慢日志功能_面试常用sql语句

面试官:创建表的时候,你们是如何优化的呢?

候选人:我们主要参考的是阿里所出的开发手册《嵩山版》,比如说,在定义字段之际,要依据字段的内容去挑选适宜的类型,要是属于数值类的,像tinyint、int 、bigint这些类型一样,得按照实际状况加以选择。倘若为字符串类型,同样是结合所要存储的内容来抉择char和varchar或者text类型。

面试官:那在使用索引的时候,是如何优化呢?

候选人:【参考索引创建原则 进行描述】

面试官:你平时对sql语句做了哪些优化呢?

候选人提到,有不少情况,像是SELECT语句一定得指明字段名称,不能直接用select * ,另外还要留意SQL语句防止造成索引失效的写法;要是进行聚合查询,最好用union all替代union ,因为union会多一次过滤,效率相对较低;倘若涉及表关联,尽量采用innerjoin ,别用left join right join,要是必须使用,务必以小表作为驱动。

面试官:事务的特性是什么?可以详细说一下吗?

嗯,有个较为清晰的情况,存在这样一组说法,ACID,它所分别指代的内容是,原子性,一致性,隔离性,持久性。

我举个例子:

有一种情况是,A给B转了500,转过去这个行为成功了,A那边少了500块钱,B这边多了500块钱,而且这种操作有个特点是,要么同时在各处都顺利成功,要么各处都遭遇失败,形成一种看起来很特别的原子操作。

于转账之时,数据得保持一致,A减去或扣除了500,那么B必然要增添或增加500。

在转账的过程中,隔离性体现在A像B转账,不能受其他事务干扰

在进行转账这个过程期间,持久性所呈现出来的情况是,当事务完成提交以后,需要将数据进行持久化处理,也就是可以称作是落盘操作。

面试官:并发事务带来哪些问题?

候选人:

我们于项目开发期间,多个事务会同时进行,这是常常出现的情况,并发是肯定会有的,而这有可能致使一些问题出现。

在事务处理中,首先存在脏读这种情况,一个事务处于访问数据并对其进行修改的状态,且此修改尚未提交至数据库,就在这个时候,另一个事务也对该数据进行了访问,由于所访问的数据是尚未提交的数据,所以另一个事务读取到的数据属于“脏数据”,基于“脏数据”开展的操作极有可能是不正确的。

首先,存在一种情况,即不可重复读。有个事务,在其中多次读同一数据。当这个事务还没结束的时候,另一个事务也开始访问该数据。然后,在第一个事务里的两次读数据阶段,因为第二个事务进行了修改,致使第一个事务两次读取的数据出现不同。于是,就出现了这个要读两次同一地方的数据,所读出来的结果却不一样的状况,所以这就被称作不可重复读。

第三被称作幻读(Phantom read),幻读跟不可重复读相类似,它出现于这种状况时而一个事务(T1)读取了好些行数据之后,紧接着另一个并发事务(T2)插入了某些数据,在后续的查询期间,第一个事务(T1)便会发觉多出了一些起初并不存在的记录,仿佛产生了幻觉一般。因而被叫做幻读。

面试官:怎么解决这些问题呢?MySQL的默认隔离级别是?

候选人:解决方案是对事务进行隔离

MySQL支持四种隔离级别,分别有:

第一个是未提交读它具有这样的情况,它没办法把刚才所提出来的全部问题给一一解决掉,一般的项目里面也是不会使用这个的。

首先,第二个呢,是读已提交,也就是read committed呀 ,它能够在一定程度上解决脏读这一问题呢 ,然而呀 ,其却没办法解决不可重复读的状况以及幻读这类情况哟。

第三个是可重复读,也就是repeatable read,它能够解决脏读以及不可重复读的情况,不过却解决不了幻读,而这同样也是mysql默认的隔离级别。

第四个是串行化,也就是serializable,它能够解决刚才所提出来的全部问题,然而因为是使事务串行执行的缘故,性能相对较低。所以,我们通常所使用的皆是mysql默认的隔离级别,即可重复读。

面试官:undo log和redo log的区别

好的,redo log日志所记录的是数据页的物理变化,服务出现宕机情况时,它能够被用于同步数据,然而undo log与之不同,它主要记录的是逻辑日志,每当事务进行回滚时,依靠逆操作来恢复至原来的数据,举例来说,当我们删除一条数据之际,就会于undo log日志文件当中新增一条delete语句,要是发生回滚,那就执行逆操作。

redo log对事务的持久性起到了保证作用,undo log对事务的原子性以及一致性起到了保证作用。

面试官问,事务里的隔离性是怎样进行保证的呀,你去解释一下MVCC?

候选人:

事务的隔离性是由锁和mvcc实现的。

当中mvcc的含义是那多版本并发控制,用以表明要维持一个数据的好多版本,致使读写操控不存在冲突,其底层的予以实现大致被划分成了三个部分,其一为隐藏着部分,其二为undo log日志,其三是readView读视图。

意味着要提到的是如下状况:存在这样一种设置,即在mysql里,针对每一个都设定有隐藏字段而言,包括两个。其当中一个是trx_id,确切说法是具有指代每次操作产生的事务id的作用,还有进一步特定内容,那就是它是自增的构成;而另外一个叫做roll_pointer,它所具有的指向含义是上一个版本的事务版本记录的地址之处。

undo log 的主要作用在于记录回滚日志,用以存储老版本数据,其在内部会形成一个版本链,当存在多个事务并行操作某一行记录时,能记录不同事务修改数据的版本,借助 roll_pointer 指针形成一个链表。

解决readView相关问题的是关于一个事务查询选择版本的情况,在其内部定义好多匹配规则,还有当前一些事务id,依据这些去判断该访问哪个版本的数据,不同隔离级别下快照读存在差异,最终访问结果也不一样。要是处于rc隔离级别,每次执行快照读时会生成ReadView,若处于rr隔离级别,仅在事务首次执行快照读时生成ReadView,后续会复用。

面试官:MySQL主从同步原理

候选人:MySQL主从复制的关键所在是二进制日志,也就是DDL(数据定义语言)语句以及DML(数据操纵语言)语句,而它实施的步骤呈现出如下这般的情况:

其一,当主库进行事务提交这个动作的时候,它会将数据发生的变更记录在被称作二进制日志文件的 Binlog 里面。

其二:于从库那儿读取主库的二进制日志文件Binlog,接着写入到从库的中继日志Relay Log。

第三:从库重做中继日志中的事件,将改变反映它自己的数据

面试官:你们项目用过MySQL的分库分表吗?

候选人:

嗯,鉴于我们均为从事微服务开发,每一个微服务都对应着一个数据库,此乃依据业务予以拆分的,这实际上便是垂直拆分。

面试官:那你之前使用过水平分库吗?

候选人:

嗯呐嗯呐然后呢这个东西真的是被使用过的,我们那个时候所存在的业务它具体是(xxx),最开始的时候,我们也和其他情况一样是单库的,往后,这个业务开始慢慢不断地发展起来了,而且业务量增长得那叫一个迅速,其中(xx)表呢已经存储了数量超过1000万的数据,我们针对此做了好多好多的优化措施,可弄完之后发现根本就没起到啥作用,性能依旧是特别特别的缓慢,所以呢在那个时候就采用了水平分库这种方式。

我们最初先制作了三台服务器,这三台服务器分别对应了三个数据库,因为数据库数量增多了,所以需要进行分片,当时我们采用的是mycat作为数据库的中间件,数据全部是依照id(自增)取模的方式来进行存取的。

最开始的时候,针对那些旧数据,进行了一些清洗工作,依据id取模规则,分别存储到各个数据库里,这样做的好处在于,能让各个数据库去分摊存储以及读取的压力,进而解决了当时性能方面的问题。

微信扫一扫分享资讯
客服服务热线
13485538018
24小时服务
微信公众号
手机浏览

CopyrightC 2009-2025 All Rights Reserved 版权所有 芜湖人才网 本站内容仅供参考,不承担因使用信息、外部链接或服务中断导致的任何直接或间接责任,风险自担。如有侵权,请联系删除,联系邮箱:ysznh@foxmail.com 鄂ICP备2025097818号-15

地址: EMAIL:qlwl@foxmail.com

Powered by PHPYun.

用微信扫一扫