Java 面试篇-MySQL 专题(如何定位慢查询、如何分析 SQL 语句、索引底层数据结构、什么是聚簇索引?什么是非聚簇索引?知道什么是回表查询?什么是覆盖索引?事务的特性、并发事务带来的问题?)
🔥博客主页: 【小扳_-CSDN博客】
❤感谢大家点赞👍收藏⭐评论✍
文章目录
1.0 MySQL 中,如何定位慢查询?
2.0 发现了 SQL 语句执行很慢,如何分析呢?
3.0 什么是索引?
4.0 索引的底层数据结构了解过吗?
5.0 B 树与 B+ 树的区别是什么呢?
6.0 什么是聚簇索引?什么是非聚簇索引?
7.0 知道什么是回表查询吗?
8.0 知道什么是覆盖索引吗?
9.0 MySQL 超大分页怎么处理?
10.0 索引创建原则有哪些?
11.0 什么情况下索引失效?
12.0 SQL 的优先经验有哪些?
13.0 创建表的时候,是如何优化的呢?
14.0 在使用索引的时候,是如何优化呢?
15.0 对 SQL 语句做了哪些优化呢?
16.0 事务的特性是什么?可以详细说一下吗?
17.0 并发事务带来哪些问题?
18.0 怎么解决这些问题?MySQL 的默认隔离级别是?
19.0 undo log 和 redo log 的区别是什么?
20.0 事务中的隔离性是如何保证的呢?(解释一下 MVCC)
21.0 MySQL 主从同步原理是什么?
22.0 项目用过 MySQL 的分库分表吗?
23.0 那你之前使用过水平分库吗?
1.0 MySQL 中,如何定位慢查询?
先是通过压力测试的时候,发现有些接口响应时间非常慢,查过了 2 秒。再接着通过部署运维监控系统 Skywalking,在它的报表展示中可以看到哪个接口慢,并且能分析出接口中哪部分耗时较多,包括具体的 SQL 执行时间,这样就能定位到出现问题的 SQL 。
如何没有这种监控系统,MySQL 本身也提供了慢查询日志功能。可以在 MySQL 的系统配置文件中开启慢查询日志,并设置 SQL 执行时间超过多少就记录到日志文件中,比如说项目设置的是 2 秒,超过这个时间的 SQL 就会记录在日志文件中,我们就可以在日志文件中找到执行慢的 SQL 语句。
2.0 发现了 SQL 语句执行很慢,如何分析呢?
如果一条 SQL 执行很慢,通常会使用 MySQL 的 EXPLAIN 命令来分析这条 SQL 的执行情况。通过 key 和 key_len 可以检查是否命中了索引,如果已经添加了索引,也可以判断索引是否有效。通过 type 字段可以查看 SQL 是否有优化空间,比如是否存在全索引扫描或全表扫描。通过 extra 建议可以判断是否出现回表情况,如果出现,可以尝试添加索引或修改返回字段来优化。
3.0 什么是索引?
索引在项目中非常常见,它是一种帮助 MySQL 高效获取数据的数据结构,主要用来提高数据检索效率。降低数据库的 I/O 成本。同时,索引列可以对数据进行排序,降低数据排序的成本,也能减少 CPU 的消耗。
4.0 索引的底层数据结构了解过吗?
MySQL 默认存储引擎 InnoDB 使用的是 B+ 树作为索引的存储结构。选择 B+ 树的原因包括:节点可以有更多子节点,路径更短;磁盘读写代价更低,非叶子节点只存储键值和指针,叶子节点存储数据;B+ 树适合范围查询和扫描,因为叶子节点形成了一个双向链表。
5.0 B 树与 B+ 树的区别是什么呢?
B 树和 B+ 树的主要区别在于:
1)B 树的非叶子节点和叶子节点都存放数据,而 B+ 树的所有数据只出现在叶子节点,这使得 B+ 树在查询效率更稳定。
2)B+ 树在进行范围查询时效率更高,因为所有数据都在叶子节点,并且叶子节点之间形成了双向链表。
6.0 什么是聚簇索引?什么是非聚簇索引?
聚簇索引是指数据与索引放在一起,B+ 树的叶子节点保存了整行数据,通常只有一个聚簇索引,一般是由主键构成。
非聚簇索引则是数据与索引分开存储,B+ 树的叶子节点保存的是主键值,可以有多个非聚簇索引,通常可以自定义的索引都是非聚簇索引。
7.0 知道什么是回表查询吗?
回表查询是指通过二级索引找到对应的主键值,然后再通过主键值查询聚簇索引中对应整行数据的过程。
8.0 知道什么是覆盖索引吗?
覆盖索引是指在 SELECT 查询中,返回的列全部能在索引中找到,避免了回表查询,提高了性能。使用覆盖索引可以减少对主键索引的查询次数,提高查询效率。
9.0 MySQL 超大分页怎么处理?
超大分页通常发生在数据量大的情况下,使用 LIMIT 分页查询且需要排序时效率较低。可以通过覆盖索引和子查询来解决。首先查询数据的 ID 字段进行分页,然后根据 ID 列表用子查询来过滤这些 ID 的数据,因为查询 ID 时使用的是覆盖索引,所以效率可以提升。
10.0 索引创建原则有哪些?
创建索引的原则包括:
1)表中的数据量超过 10 万以上时考虑创建索引。
2)选择查询频繁的字段作为索引,如查询条件、排序条件或分组字段。
3)尽量使用复合索引,覆盖 SQL 返回值。
4)如果字段区分度不高,可以使用前缀索引。
5)控制索引数量,因为索引虽然可以提高查询速度,但也会影响插入、更新的速度。
11.0 什么情况下索引失效?
索引可能在以下情况下失效:
1)没有遵循最左匹配原则。
2)使用了模糊查询且 % 号在前面。
3)在索引字段上进行了运算或类型转换。
4)使用了复合索引但在中间使用了范围查询,导致右边的条件索引失效。
12.0 SQL 的优先经验有哪些?
SQL 优先可以从以下几个方面考虑:
1)建表时选择合适的字段类型。
2)使用索引,遵循创建索引的原则。
3)编写高效的 SQL 语句,比如避免使用 SELECT *,尽量使用 UNION ALL 代替 UNION,以及在表关联时使用 INNER JOIN 。
4)采用主从复制和读写分离提高性能。
5)在数据量大时考虑分库分表。
13.0 创建表的时候,是如何优化的呢?
创建表的时候,主要参考《嵩山版》开发手册,选择字段类型时结合字段内容,比如数值类型选择 TINYINT、INT、BIGINT 等,字符串类型选择 CHAR、VARCHAR 或 TEXT 。
14.0 在使用索引的时候,是如何优化呢?
在使用索引时,遵循索引创建原则,确保索引字段是查询频繁的,使用复合索引覆盖 SQL 返回值,避免在索引上进行运算或类型转换,以及控制索引数量。
15.0 对 SQL 语句做了哪些优化呢?
对 SQL 语句的优化包括指明字段名称而不是使用 SELECT *,避免造成索引失效的写法,聚合查询时使用 UNION ALL 代替 UNION,表关联时优先使用 INNER JOIN,以及在必须使用 LEFT JOIN 或 RIGHT JOIN 时,确保小表作为驱动表。
16.0 事务的特性是什么?可以详细说一下吗?
事务的特性是 ACID,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。比如,A 向 B 转账 500 元,这个操作要么都成功,要么都失败,体现了原子性。转账过程中数据要保持一致,A 扣除了 500 元,B 必须增加 500 元。隔离性体现在 A 向 B 转账时,不受其他事务干扰。持久性体现在事务提交之后,数据要被持久化存储。
17.0 并发事务带来哪些问题?
并发事务可能导致脏读、不可重复读和幻读。脏读是指一个事务读到了另一个事务未提交的 "脏数据" 。不可重复读是指在一个事务内多次读取同一数据,由于其他事务的修改导致数据不一致。幻读是指一个事务读取到了其他事务插入的 "幻行" 。
18.0 怎么解决这些问题?MySQL 的默认隔离级别是?
解决这些问题的方法是使用事务隔离。MySQL 支持四种隔离级别:
1)未提交读(READ UNCOMMITTED):解决不了所有问题。
2)读已提交(READ COMMITED):能解决脏读,但不能解决不可重复读和幻读。
3)可重复读(REPEATABLE READ):能解决脏读和不可重复读,但不能解决幻读,这也是 MySQL 的默认隔离级别。
4)串行化(SERIALIZABLE):可以解决所有问题,但性能较低。
19.0 undo log 和 redo log 的区别是什么?
redo log 记录的是数据页的物理变化,用于服务宕机后的恢复,保证事务的持久性。而 undo log 记录的是逻辑日志,用于事务回滚时恢复原始数据,保证事务的原子性和一致性。
20.0 事务中的隔离性是如何保证的呢?(解释一下 MVCC)
事务的隔离性通过锁和多版本并发控制(MVCC)来保证。MVCC 通过维护数据的多个版本来避免读写冲突。底层实现包括隐藏字段、undo log 和 read view。隐藏字段包括 trx_id 和 roll_pointer。undo log 记录了不同版本的数据,通过 roll_pointer 形成版本链。read view 定义了不同隔离级别下的快照读,决定了事务访问哪个版本的数据。
21.0 MySQL 主从同步原理是什么?
MySQL 主从复制的核心是二进制日志(Binlog)。步骤如下:
1)主库在事务提交时,记录数据变更到 Binlog 。
2)从库读取主库的 Binlog 并写入中继日志(Relay Log)。
3)从库重做中继日志中的事件,反映到自己的数据中。
22.0 项目用过 MySQL 的分库分表吗?
项目中采用微服务架构,每一个微服务对应一个数据库,是根据业务进行拆分的,这个其实就是垂直拆分。
23.0 那你之前使用过水平分库吗?
使用过。当时业务发展迅速,某个表数据量超过 1000 万,单库优化后性能仍然很慢,因此采用了水平分库。首先部署了 3 台服务器和 3 个数据库,使用 mycat 进行数据分片。旧数据也按照 ID 取模规则迁移到各个数据库中,这样数据库可以分摊存储和读取压力,解决了性能问题。
希望这篇文章可以帮助到您,可以解决您的燃眉之急。如果还需要更加详细的 MySQL 的内容,请关注:MySQL 篇_小扳的博客-CSDN博客