当前位置: 首页 > article >正文

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博客


http://www.kler.cn/a/557667.html

相关文章:

  • 答题卡识别阅卷系统(Matlab)
  • sklearn中的决策树-分类树:重要参数
  • 本地化部署 DeepSeek:从零到一的完整指南
  • DeepSeek03-ollama本地部署DeepSeek(NSFW)
  • leetcode 题目解析 第3题 无重复字符的最长子串
  • 标准I/O与文件I/O
  • 【DeepSeek-R1背后的技术】系列八:位置编码介绍(绝对位置编码、RoPE、ALiBi、YaRN)
  • Spring MVC 对象转换器:初级开发者入门指南
  • 【跟我学YOLO】(1)YOLO12:以注意力为中心的物体检测
  • 简聊RocketMQ如何确保顺序性
  • HADOOP_HOME and hadoop.home.dir are unset.
  • php处理图片出现内存溢出(Allowed memory size of 134217728 bytes exhausted)
  • 【网络编程】服务器模型(二):并发服务器模型(多线程)和 I/O 复用服务器(select / epoll)
  • 【多语言生态篇四】【DeepSeek×Rust:安全内存管理实践】
  • verilog笔记
  • 【Leetcode 每日一题 - 扩展】1512. 好数对的数目
  • C语言实现的常见算法示例
  • 【算法】直接插入排序、折半插入排序、希尔排序
  • Dockerfile中volume功能作用
  • ok113i平台——更改根目录分区大小