MySQL核心知识复盘:索引、事务、锁与主从复制实战
2026/9/19 6:09:18 网站建设 项目流程

最近在准备MySQL相关的面试和日常开发的问题排查,我把平时零零散散学到的知识点整理成了一套自己的复习笔记。这套笔记不仅是为了应付面试里那些高频问题,更重要的是帮我在真正写SQL、做表结构设计、排查慢查询的时候,能少走一些弯路。今天把这些笔记的核心内容分享出来,围绕MySQL的架构、索引、事务、锁、日志和主从复制这几个大块展开,每个部分我都会结合自己的理解和实际踩过的坑来说明。

这不是一份“背诵版”的面试答案集,更像是一份带着思考过程的复习记录。我会尽量把每个知识点背后的“为什么”讲清楚,也会把我在实操中遇到的一些典型问题整理成清单,方便你直接对照自己的项目经验来做复盘。

1. MySQL整体架构:一条SQL语句的完整旅程

1.1 Server层与存储引擎层是怎么分工的

刚开始学MySQL的时候,我习惯性把它当成一个黑盒,只管写SQL、拿结果。但后来遇到很多问题,比如同一个SQL在不同版本的MySQL上表现不一样,或者同样的表结构用InnoDB和MyISAM得到的结果完全不同,我才意识到必须要先搞清楚MySQL的分层架构。

MySQL从宏观上分两层:Server层和存储引擎层。Server层是全局通用的,包括连接器、查询缓存(8.0之前)、分析器、优化器、执行器,还有内置函数、存储过程、触发器这些都在这一层。存储引擎层是插件式的,负责真正的数据读写,InnoDB、MyISAM、Memory这些都是存储引擎的实例。你在建表时指定ENGINE=InnoDB,就是在给这张表选定具体的存储引擎。

这种分工方式最直接的影响就是:SQL语句的解析、优化、执行路径是走Server层,但数据文件的组织方式、索引的实现结构、事务支持和锁粒度,全由存储引擎决定。比如InnoDB支持事务和行锁,MyISAM只支持表锁;同样是创建索引,InnoDB的索引和数据是绑在一起的,MyISAM的索引和数据是分开存的。

1.2 一条查询语句要经过哪些环节

我习惯把一条SELECT语句的完整流程类比成一个外卖订单的处理过程。你下单(连接器验证身份);订单进入到系统的初步校验(分析器做词法和语法分析);系统根据你的账号和门店判断最优出餐路线(优化器决定走哪个索引、怎么关联表);最后骑手拿着小票去对应窗口取餐(执行器调用存储引擎接口去拿数据)。

具体来说,连接器负责和客户端建立连接、验证账号密码、维护权限和连接状态。分析器做的是词法分析,把SQL拆成关键字、表名、字段名,然后做语法分析,确认你的SQL没有语法错误。优化器负责决定用什么索引、怎么连接表,以及调整执行顺序。执行器在拿到优化器的执行计划之后,开始逐条调用存储引擎的接口,最终把结果返回给客户端。

这里有一个很关键的点:很多新手以为SQL执行慢就是索引没建好,但实际上慢的可能发生在任何一个环节。比如连接超时、权限校验复杂、优化器选错索引、存储引擎层锁等待严重,都可能导致最终响应变慢。所以定位问题的时候一定不能只看执行计划,还要结合连接状态、锁等待情况、日志信息综合判断。

1.3 查询缓存为什么被移除了

在MySQL 8.0之前,Server层有一个查询缓存模块,它会把SELECT语句和对应的结果集缓存起来,如果后续有完全相同的查询,就直接返回缓存结果,不再往下执行。听起来很高效,但在实际业务中查询缓存的命中率通常很低,而且维护成本很高。

问题在于只要表上的数据发生任何更新,所有涉及该表的查询缓存就会全部失效。对于写入频繁的表,缓存刚建立就被清掉,反而是额外开销。MySQL 8.0索性把查询缓存移除了。我个人的经验是,不要过度依赖这种机制带来的“免费性能提升”,应用层用Redis做缓存才是更可控的方案,缓存失效策略、过期时间、热点数据的预热都能自己掌控。

2. 索引机制与SQL优化要点

2.1 B+树索引为什么是InnoDB的默认选择

索引是MySQL面试里绕不开的话题,而B+树又是InnoDB索引的核心结构。我刚开始复习这个点的时候,一直在想为什么不用哈希索引、二叉树或者B树。后来把数据结构的特点和磁盘IO的特性结合起来看,思路就清晰了。

哈希索引虽然查询效率是O(1),但它不支持范围查询,也不支持前缀模糊匹配,更没法按顺序扫描数据,所以只适合“等值查询”这种极少数的场景。二叉树的层数会随着数据量增长变得很深,每访问一层节点就相当于一次磁盘IO,数据量大时IO次数太多。B树把多个键值放在同一个节点中,树的高度大大降低,但B树的每个节点既存索引又存数据,导致非叶子节点能容纳的索引项变少。

B+树把数据都放在叶子节点上,并且叶子节点用链表串起来,这样有几个好处:非叶子节点可以存更多的键值,树更矮更宽,减少磁盘IO;同时叶子节点顺序排列,非常适合范围查询和排序;再加上每个叶子节点都有指向下一个叶子节点的指针,全表扫描时只需顺序读叶子节点链表就可以。

2.2 最左前缀规则和联合索引的设计

联合索引(也叫复合索引)在实际项目里几乎天天都要用,但很多人只知道“最左前缀”这几个字,遇到具体SQL就判断不准。

我先说结论:最左前缀说的是,查询条件中必须包含联合索引最左边的列,并且这个列的匹配要足够“靠左”,索引才能被充分利用。比如我在一张订单表上建立了联合索引(customer_id, status, create_time),那么在查询条件里,如果只有status或只有create_time,这个索引就基本用不上;如果条件是customer_id和status,则索引可以命中;如果条件是customer_id、status和create_time,那就是完全命中索引。

为什么会有这个限制?因为联合索引的排序是先把最左边的列排好,左边一样再排第二列,依次类推。字符串比较也是同样的道理,相当于索引数据是一棵“按优先级排序”的树。我在设计联合索引时,一般会遵循“区分度高的列放前面”、“常用等值查询的列放前面”、“范围查询的列尽量放后面”这几个原则,但这也不是绝对的,实际还得结合业务查询频率来权衡。

2.3 回表、覆盖索引和索引下推

回表这个问题,我是在做报表查询优化时真正感受到它有多贵的。InnoDB的主键索引就是聚簇索引,叶子节点存的是整行数据。而普通索引(二级索引)的叶子节点存的是主键值和索引列的值。当你通过普通索引查询,但需要的字段不在这个索引里的,就需要拿着主键再去主键索引里找一次完整行,这个过程就叫回表。

减少回表的办法主要有两个:一是建立覆盖索引,让查询需要的字段全都在同一个二级索引里,这样连回表都省了;二是借助索引下推(Index Condition Pushdown, ICP),在存储引擎层就过滤掉一部分不满足条件的记录,减少返回给Server层的行数。MySQL 5.6之后默认开启索引下推,对联合索引的LIKE模糊查询尤其有效。

举个具体场景,我有一张文员信息表,表结构大概包括emp_id、name、age、department、phone。如果有一条高频SQL是“按部门查员工姓名和工号”,我就建立联合索引(department, emp_id, name),让查询结果直接从索引里取,完全避免回表。这个优化看起来很简单,但数据量上百万的时候,减少的回表次数可能就是几万次。

2.4 执行计划到底应该怎么看

每次排查慢SQL,第一件事就是EXPLAIN。但EXPLAIN的结果不是背下每个字段就能解决问题,得能看出关键字段之间的逻辑关系。

我最先关注的是type字段,它描述了访问类型。从好到坏大致有system、const、eq_ref、ref、range、index、ALL。ALL是全表扫描,基本意味着索引没起作用或者没有合适的索引;index表示扫描了整棵索引树,比ALL好点,但也需要警惕。range表示范围扫描,通常和BETWEEN、IN、LIKE前缀等操作相关。ref和eq_ref表示用到了非唯一索引和唯一索引的等值匹配,是比较理想的访问类型。

接下来我会看key和rows。key表示实际用到的索引,有时候优化器可能没选你心里预期的索引,那就需要分析为什么,甚至考虑用FORCE INDEX或改写SQL。rows是估算的需要扫描的行数,但它是估算值,不是实际值,不能完全依赖。Extra字段里如果出现Using filesort或Using temporary,就要格外注意,前者代表排序没走索引,后者代表查询使用了临时表,这两类操作在高并发场景下非常吃资源。

3. 事务、隔离级别与锁机制

3.1 ACID到底靠什么来保证

事务是InnoDB区别于MyISAM的核心能力之一。ACID四个特性——原子性、一致性、隔离性、持久性,我在面试里被问过很多次,但真正理解它们的实现机制,是最近补课才做到的。

原子性靠undo log来保证。事务执行过程中如果发生回滚,就用undo log里的记录把数据恢复到事务开始前的状态。隔离性靠锁和MVCC来保证。持久性靠redo log,事务提交后,即使系统崩溃,redo log里也有记录,重启后可以恢复。一致性是从应用层和数据库层的配合来审视的,如果原子性、隔离性、持久性都满足了,一致性通常也就有了基础保障。

这里有个容易混淆的点:redo log和undo log都叫“日志”,但作用完全不同。redo log是物理日志,记录的是“数据页做了什么修改”;undo log是逻辑日志,记录的是“事务修改之前的数据是什么”。细节我在后面讲日志系统时再展开。

3.2 四种隔离级别在并发下分别会出现什么问题

SQL标准定义了四种隔离级别:读未提交、读已提交、可重复读、串行化。我复习这部分时,最有效的方式是画一张并发场景对比表,把“脏读、不可重复读、幻读”这几个问题对应到隔离级别上。

脏读是读到了别的事务还没提交的数据,一旦对方回滚,你的数据就是错的。读未提交级别允许脏读,现实中基本不用。读已提交解决了脏读,但同一事务里两次查询结果可能不同,这就是不可重复读。可重复读解决了不可重复读,也就是事务开始后读到的数据保持一致,但InnoDB在这个级别下通过间隙锁也比较好地解决了幻读问题。串行化则是让并发事务完全串行执行,性能最差。

MySQL默认的隔离级别是可重复读,这和Oracle默认的读已提交不一样。原因之一是MySQL的BinLog在主从复制场景下,可重复读配合间隙锁能更安全地保持一致。实际业务中,如果对一致性要求不是极致,读已提交有时候性能会更好,因为锁竞争更小。

3.3 MVCC是怎么实现快照读的

MVCC这个名词听起来很高级,其实本质就是:让读操作和写操作不互相阻塞。InnoDB给每一行记录隐式加了两列:一个是事务ID,一个是回滚指针。事务ID用于判断版本新旧,回滚指针指向undo log里上一个版本的数据。

在可重复读级别下,事务第一次执行快照读时,会生成一个ReadView,里面记录了当前活跃事务列表。之后该事务再读取数据时,只会读取版本号小于等于自己可见版本的数据。因为ReadView在第一次快照读时就确定了,所以整个事务期间看到的数据版本是一致的,这就避免了不可重复读。

我在复习MVCC时最大的感想是,它只对快照读(普通SELECT)起作用,对于当前读(如SELECT ... FOR UPDATE、UPDATE、DELETE)仍然使用最新的数据版本,并且要加锁。所以“可重复读解决了幻读”这句话并不是万能的,在业务里如果先快照读再当前读,仍然可能出现幻读场景。

3.4 InnoDB的锁类型和加锁规则

InnoDB的锁分两类:共享锁(S锁)和排他锁(X锁)。读写操作之间会互相影响,所以加了S锁之后其他事务还可以加S锁,但不能加X锁;加了X锁之后,其他事务既不能加S锁也不能加X锁。

按粒度分,有行级锁和表级锁,InnoDB支持行锁,MyISAM只有表锁。行锁的实现又分为记录锁、间隙锁和临键锁。记录锁锁定一行记录;间隙锁锁的是记录之间的区间,用来解决幻读;临键锁是记录锁和间隙锁的组合,锁定当前记录和前面的间隙。

在实际排查死锁的时候,我总结出一个规律:死锁通常发生在多个事务以不同的顺序申请同一个资源集合时。比如事务A先更新id=1再更新id=2,事务B先更新id=2再更新id=1,两边互相等待,就形成死锁。解决思路是让所有事务都按照相同的顺序访问资源,如果确实无法避免,也可以利用数据库的死锁检测机制,让其中一方快速回滚。

4. 日志系统与主从复制

4.1 redo log的WAL机制带给我们什么启发

MySQL的持久性保证主要靠redo log,它采用WAL(Write-Ahead Logging)策略,意思是先写日志,再写磁盘数据页。为什么要这么设计?因为直接刷数据页是随机IO,很慢;而写redo log是顺序追加,速度快得多。这样即使数据页还没刷新到磁盘,事务只要把redo log刷盘就可以先提交了;万一系统崩溃,重启后靠redo log把数据页恢复。

这个思路其实特别像很多工程里的“先记账、后清账”。我先在账本上记一笔“你要改什么”,等晚上或者空闲了再把账目落到正式账本上。账本只是日志文件,崩溃后也能凭账本恢复,不会丢数据。

InnoDB的redo log是循环写的,有固定大小,比如我用过的1GB配置。如果写入速度快过数据页的刷盘速度,会触发checkpoint,把老日志对应的脏页刷到磁盘。这里有个调优点:redo log文件太小会导致频繁刷盘,降低性能;太大又会增加崩溃恢复时间。具体大小需要结合业务写入量来评估,我一般会观察日志写入趋势和checkpoint频率来调整。

4.2 binlog和redo log的区别以及两阶段提交

binlog是MySQL Server层产生的逻辑日志,记录的是SQL语句的原始逻辑或行变更,主要用于主从复制和时间点恢复。redo log是InnoDB存储引擎层的物理日志,记录的是“哪个数据页的哪个偏移量改成了什么”。

两者最大的区别是:redo log是物理日志、循环写、不等同于全量备份;binlog是逻辑日志、追加写、保留了全部历史变更。redo log决定了崩溃恢复后数据不丢,binlog决定了从库能同步主库的变更。

为了保证主库崩溃时redo log和binlog都能保持一致,MySQL引入了两阶段提交。事务提交时先写redo log并处于prepare状态,然后写binlog,最后把redo log改为commit状态。这是我复习时觉得最难理解、也最值得深挖的部分,因为它本质上解决的是“两个不同层的日志如何原子化”的问题。

4.3 主从复制的基本流程和常见延迟原因

主从复制是读写分离的基础。它的核心流程是:主库把变更记录写到binlog,从库的IO线程从主库拉取binlog并写到自己的中继日志,从库的SQL线程再执行中继日志里的内容,将变更应用到自己的数据上。整个过程是异步的,所以主从天然存在延迟。

最常见的延迟原因是主库上大事务执行时间过长,比如一次性批量更新几十万行数据,对应的binlog体积也大,从库要重放这些变更,速度跟不上。还有一种情况是从库所在机器的性能比主库差,或者从库还承担了比较重的分析查询。排查时我一般用SHOW SLAVE STATUS,关注Seconds_Behind_Master字段,如果这个值持续上涨,就需要检查主库的大事务和从库的硬件负载。

我在设计读写分离时的一个建议是:对一致性要求非常高的场景,不要把读写分离方案做得太粗暴,宁可让部分读流量也走主库,也不要因为从库延迟让用户看到明显的数据不一致。

5. JSON字段、存储过程与易错SQL实战

5.1 JSON字段到底要不要用

现在的业务里经常会有动态属性,比如商品列表里有不同的规格扩展字段,如果用传统的关系型字段设计,要么预定义很多可空列,要么拆子表。MySQL 5.7之后提供了JSON类型,用起来确实方便,但并不是所有场景都适合。

JSON字段的优势是灵活,但劣势也很明显:不能对JSON内部字段直接建常规索引(需要生成列或者用多值索引),更新JSON字段通常是整体重写,性能损耗大。我在项目里一般只把JSON用于低频更新的配置信息、扩展属性、或者非核心查询条件的元数据。如果需要频繁按JSON里的某个字段做条件查询和排序,还是建议拆成独立字段或者子表。

5.2 定义存储过程时的常见坑

存储过程这个东西,在面试八股里经常出现,但实际业务中我用得比较少。主要原因是业务逻辑放在应用层更好维护,数据库只负责存储、索引和事务。不过有些场景,比如定时任务要批量处理数据,或者要做复杂的数据清洗,写一个存储过程也能让代码更集中。

在写存储过程时我踩过的一个坑是:如果同时用到了动态SQL和预处理,忘记释放PREPARE STMT,连接长时间运行后会累积内存和临时对象,导致性能下降。还有一个坑是存储过程里的异常处理,默认情况下出错不一定立刻回滚,需要主动声明DECLARE EXIT HANDLER FOR SQLEXCEPTION。所以如果你决定用存储过程,请一定把异常处理逻辑写得显式化。

5.3 子查询更新和DELETE/UPDATE时的语法细节

MySQL里执行UPDATE或DELETE时,如果目标表和子查询引用了同一张表,有时候会报错“You can't specify target table for update in FROM clause”。这个报错在整理更新语法时很容易遇到。解决办法是给子查询再做一层临时表包装,强制MySQL先物化一份数据再更新。

举个例子,我想删除订单表里那些“总金额低于平均水平”的订单,如果把目标表和聚合查询放在同一个DELETE里,MySQL可能不配合。我一般会先写SELECT验证一下,确认逻辑没问题,再用SELECT的结果构造要删除的主键列表,或者给子查询套一层别名来绕过限制。

5.4 常用SQL函数的适用范围

MySQL提供了一大堆内置函数,但很多人分不清什么时候能用索引、什么时候一定全表扫。比如对索引列使用函数,例如WHERE DATE(create_time) = '2025-01-01',这个写法会导致索引失效,因为索引存储的是原始字段值,MySQL得先把每一行的create_time转换成日期再比较。改成范围查询WHERE create_time >= '2025-01-01 00:00:00' AND create_time < '2025-01-02 00:00:00',就能走索引。

字符串函数、日期函数、聚合函数这些确实常用,但用的时候要考虑对执行计划的影响。印象比较深的还有GROUP_CONCAT和JSON_OBJECT搭配,能把一对多关系轻松转化为一行JSON字符串,在做报表接口时很省事。

6. 面试八股题的高频复盘与排查技巧

6.1 你被问过哪些“看似简单但不好答”的问题

面试里MySQL的八股题,最常见的几个方向我都遇到过:索引为什么用B+树;事务隔离级别分别解决什么问题;MVCC的ReadView什么时候生成;一条SQL执行很慢怎么排查;主从延迟怎么处理;优化器为什么不走索引等等。

这些问题表面上是考记忆,实际上考的是你有没有真实排障经验。比如“一条SQL执行很慢怎么排查”,光是背书式回答“加索引”肯定不够,我觉得至少要说清以下步骤:先用EXPLAIN看执行计划,确认是否全表扫描;用SHOW PROFILE或者Performance Schema看各阶段耗时;查看当前是否有锁等待,用information_schema.innodb_trx和sys.innodb_lock_waits排查;再看索引区分度和数据分布,确认优化器是否选错了索引;最后再考虑改写SQL结构或者调整索引。

6.2 排障实战:慢查询日志到底怎么抓

排查慢SQL的第一步通常是开慢查询日志,但很多人的配置方式不对。我在复习这个点时记了几个关键参数:slow_query_log用来开启慢查询日志;long_query_time用来设定阈值,单位是秒,我一般会设为1秒;log_queries_not_using_indexes表示是否记录没有走索引的SQL。

日志开启后,可以借助mysqldumpslow工具来做简单的统计,或者用pt-query-digest这类第三方工具做更详细的聚合分析。我自己在定位问题时,更喜欢直接用Performance Schema的events_statements_summary_by_digest来按语句摘要聚合,这样不用在大量日志里人工翻找。

6.3 索引失效的场景我都记成了清单

整理笔记时,我把索引失效的常见场景做了一张清单,方便平时写SQL时对照:

  • 对索引列使用函数或表达式计算,例如WHERE id + 1 = 10
  • 隐式类型转换,例如字符串字段和数字比较
  • LIKE以通配符开头,例如LIKE '%keyword'
  • 联合索引不满足最左前缀
  • 使用OR连接条件,且其中一列没有索引
  • 优化器判断全表扫描比索引扫描更快,比如表中大部分行都满足WHERE条件

这些场景里面,“优化器认为全表扫描更快”是最容易被忽略的。有时候你以为建了索引就万事大吉,但数据分布非常不均匀,比如status字段90%的记录都是同一个值,查询这个值的时候优化器会觉得走索引太麻烦,直接全表扫描更划算。

6.4 死锁问题的定位与处理心得

死锁发生后,数据库会自动回滚其中一个事务,然后会往错误日志里写死锁信息。我在排查死锁时,常用SHOW ENGINE INNODB STATUS来查看最近一次死锁的详细信息,里面会列出两个事务正在等待的锁、持有的锁以及涉及的SQL语句。

有一次我在批量更新用户积分时遇到死锁,原因是两个并发请求各自更新了不同用户,但资源申请顺序恰好交叉。我调整了业务逻辑,让所有批量更新统一按用户ID排序后再执行,死锁就基本消失了。所以处理死锁的关键不是说死锁有多可怕,而是理解触发条件,让业务操作保持稳定的资源访问顺序。

7. MySQL 8.0和Docker环境下的一些实操经验

7.1 MySQL 8.0相比5.7有哪些变化

日常学习和新项目规划时,我基本都从MySQL 8.0起步。8.0移除了查询缓存,默认字符集变成了utf8mb4,新增了窗口函数、公用表表达式(CTE)、检查约束、多值索引等能力。对于复杂报表查询,窗口函数和CTE真的能简化很多SQL。

还有一点是账号认证插件的变化,8.0默认使用caching_sha2_password,如果拿老版本的客户端连接,有可能会因为插件不一致导致认证失败。我遇到过Navicat老版本连接不上8.0的情况,解决方法是升级客户端或者把账号的认证插件改回mysql_native_password,但要注意这对密码存储安全的影响。

7.2 用Docker快速起一个MySQL实例

为了复现测试环境,我经常用Docker起MySQL,比在本地安装完整服务更方便。最常用的一条命令大致是:

docker run -d \ --name mysql-test \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=yourpassword \ mysql:8.0

如果希望数据不丢,建议把数据目录挂载到宿主机,比如增加-v /my/own/datadir:/var/lib/mysql。这里有个小坑:挂载数据目录后,如果你新起的容器版本和之前数据目录的版本不一致,比如从5.7的目录直接挂给8.0用,启动很可能失败。数据文件版本兼容性问题在本地开发时经常遇到,不建议在没备份的情况下随意跨版本挂载。

7.3 忘记root密码怎么处理

忘记root密码是很多人都遇到过的问题。常用的办法是修改配置文件,在mysqld段加一行skip-grant-tables然后重启服务,再通过UPDATE mysql.user SET authentication_string=...来重置密码。但在8.0里这个操作方式略有变化,而且用skip-grant-tables启动时风险很大,只要是能连上这台机器的人都可以无密码登录。我个人建议重置完密码后,立刻把配置项删掉,并且用FLUSH PRIVILEGES刷新权限。

7.4 端口冲突和服务启动失败的问题

还有一个很高频的启动报错是端口被占用,表现为服务无法启动,错误日志里会提示bind失败。排查时先看3306端口被哪个进程占用,Windows上可以用netstat -ano查看,Linux上可以用ss -lntp。如果是本地同时装了多个MySQL实例,还要检查配置文件里port和socket路径是否冲突。

7.5 用Navicat或者Workbench连接时的常见问题

本地连接MySQL时,最常见的报错是Host 'xxx' is not allowed to connect to this MySQL server。这是因为MySQL默认只允许localhost连接,远程连接需要单独授权。在用Navicat或者MySQL Workbench连接时,还要注意账号是否有对应的权限,一般我会创建独立的业务账号,按最小权限分配,比如只对某个数据库有SELECT、INSERT、UPDATE、DELETE权限,而不是一直用root操作。

8. 从八股笔记到真实项目的一点思考

复习MySQL八股的过程,其实也是在给自己搭建一个“数据库全局观”。我以前写业务代码时,更多关注的是SQL能不能查出结果,不太关注执行计划是什么样的,也很少去想一个事务到底持有哪些锁,更不会去分析binlog和redo log的配合关系。把这些基础原理摸索清楚以后,再回来看业务代码里那些“偶尔慢一下”的SQL,就更容易找到背后的原因。

而且在整理笔记的过程中,我发现单纯的记忆特别容易忘,只有把知识点落到真实场景里,比如自己去Docker里起一个MySQL实例,构造几万条数据,分别测试不同索引对SQL性能的影响,才能真正理解最左前缀和回表这些概念。如果你也在准备面试或者想提升数据库方面的能力,我不建议死记硬背那些答案,更推荐把环境搭起来,跟着案例把每条SQL的执行计划都看一遍,亲手制造一个死锁,再亲手把它解开。

面试时最有说服力的,从来不是“我知道某个概念”,而是“我在某个场景里遇到过这个问题,我是这样排查和解决的”。这套八股笔记的价值,就是帮我把概念和场景衔接起来,希望我的梳理也能给你提供一个类似的思路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询