MySQL 进阶知识

MySQL 进阶学习笔记

本篇为《MySQL 基础知识》的进阶续篇,覆盖基础语法之后的核心主题:存储引擎、索引、SQL 性能分析、优化技巧、多表设计范式、视图、存储过程与触发器、事务底层(锁与 MVCC)、三大日志、备份恢复与运维常识。所有语法基于 MySQL 8.0(兼容 5.7 的差异均已标注)。


1. 存储引擎

1.1 查看与指定

sql 复制代码
SHOW ENGINES;                                    -- 查看所有引擎及支持情况
SELECT @@default_storage_engine;                 -- 查看默认引擎(8.0 默认 InnoDB)
SHOW TABLE STATUS WHERE Name = '表名'\G          -- 查看某表使用的引擎

CREATE TABLE t (...) ENGINE=MyISAM;              -- 建表时指定引擎
ALTER TABLE t ENGINE=InnoDB;                     -- 修改表引擎

1.2 InnoDB vs MyISAM 对比(高频面试)

对比项 InnoDB MyISAM
事务 支持(ACID) 不支持
锁粒度 行锁 + 表锁 仅表锁
外键 支持 不支持
崩溃恢复 靠 redo log,不易丢数据 容易损坏,需修复
全文索引 5.6+ 支持 支持
聚簇存储 是(数据随主键 B+ 树存放) 否(数据与索引分离)
count(*) 需扫描(InnoDB 8.0 优化后仍非 O(1) 精确) 维护计数器,无 WHERE 时 O(1)
适用场景 绝大多数 OLTP 场景(默认选择) 只读/缓存型表、极老版本兼容

结论:没有特殊理由一律用 InnoDB。MEMORY(堆表)引擎可用于临时缓存,重启即失。


2. SQL 性能与架构分析

2.1 查看 SQL 执行效率的常用手段

手段 说明
SHOW STATUS 查看服务器状态信息(如慢查询次数 Slow_queries)
SHOW PROCESSLIST 查看当前所有连接及其正在执行的语句(排查长事务、锁等待)
慢查询日志 slow log 记录执行时间超过阈值(long_query_time,默认 10s)的语句
EXPLAIN / DESCRIBE 查看 SQL 执行计划(最重要)
SHOW PROFILE 语句各阶段耗时剖析(5.6 后由 performance_schema 替代)
sys 库 MySQL 5.7+ 提供的运维视图集合(如 sys.session、sys.statement_analysis)

2.2 开启与使用慢查询日志

sql 复制代码
SHOW VARIABLES LIKE 'slow_query%';         -- 是否开启、日志路径
SHOW VARIABLES LIKE 'long_query_time';     -- 阈值(秒,可为小数)

SET GLOBAL slow_query_log = ON;            -- 动态开启(重启失效)
SET GLOBAL long_query_time = 1;            -- 阈值设为 1 秒

持久化写入配置文件 my.cnf(Windows 为 my.ini):

ini 复制代码
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1          -- 可选:未用索引的语句也记录

分析工具:mysqldumpslow slow.log 或第三方 pt-query-digest,可按耗时排序找出 Top SQL。

2.3 EXPLAIN 执行计划(重点)

把 EXPLAIN 加在 SELECT 前即可:

sql 复制代码
EXPLAIN SELECT * FROM employee WHERE name = '张三';

关键输出字段:

字段 含义
id 执行顺序标识:id 越大越先执行;id 相同自上而下执行。子查询/UNION 会体现在 id 上
select_type 查询类型:SIMPLE(普通)、PRIMARY(最外层)、SUBQUERY(子查询)、DERIVED(FROM 中的派生表)、UNION、DEPENDENT UNION 等
table 访问的表(含派生表别名)
type 访问类型(见下表,性能排序的核心指标)
possible_keys 可能用到的索引
key 实际使用的索引,NULL 表示未走索引
key_len 使用的索引长度(判断联合索引被用了几列)
ref 索引匹配到了哪一列/哪个常量
rows 预估要扫描的行数(越小越好)
filtered 按条件过滤后剩余行的百分比(越大越好)
Extra 附加信息(最容易被忽略也最有价值)

type 访问类型(从上到下性能由好到差):

type 说明 评价
system/const 主键/唯一索引等值命中常量,最多一行 最好
eq_ref 连接时按主键/唯一键匹配(联表常见) 优
ref 非唯一索引等值匹配 良
range 索引范围扫描(BETWEEN、>、IN) 可接受
index 全索引树扫描(通常只为排序) 差
ALL 全表扫描 最差,必须优化

生产要求:至少达到 range 级别,联表最好达到 ref,杜绝大表 ALL。

Extra 常见值解读:

Extra 含义 应对
using filesort 无法用索引完成排序,额外排序 建合适的索引让 order by 有序
using temporary 使用了临时表(常见于 group by) 优化分组/排序索引
using index 覆盖索引,无需回表 理想状态
using index condition 索引条件下推 ICP,减少回表 良好
using join buffer 连接无索引,用缓冲优化 给连接列加索引
Impossible where / Select tables optimized away 条件恒假 / MAX 等被优化 视情况

2.4 分页深翻问题

sql 复制代码
EXPLAIN SELECT * FROM t LIMIT 5000000, 10;   -- rows 巨大:先扫 500 万行再丢弃

优化:先用覆盖索引取主键,再连接回表------

sql 复制代码
SELECT a.* FROM t a
JOIN (SELECT id FROM t ORDER BY id LIMIT 5000000, 10) b ON a.id = b.id;

3. 索引(Index)

3.1 价值与代价

  • 价值:类似图书目录,把全表扫描(O(n))降为索引树查找(O(log n)),大幅减少扫描行数、随机 IO 与排序开销。
  • 代价:索引是额外文件(通常占数据 10%~20%+),降低增删改速度,不当使用反而更慢;所以不是所有表都必须要索引,中小数据量收益不明显。

3.2 使用原则

适合建索引:主键自动建索引;作为 WHERE/ORDER BY/GROUP BY/JOIN 条件且区分度高的列(经验值:COUNT(DISTINCT col)/COUNT(*) > 0.1);需要覆盖查询的列。

不适合:列极少(如性别)、频繁更新的列、大文本/二进制列、WHERE 从不用的列。

3.3 MySQL 8.0 支持的索引类型

类型 说明
MAIN KEY(PRIMARY) 唯一且非空,一表仅一个,聚簇索引
UNIQUE 唯一索引,允许 NULL
INDEX / NORMAL 普通单列索引
FULLTEXT 全文索引(分词检索,InnoDB/MyISAM 均支持)
前缀索引 对字符串列前 N 个字符建索引,节省空间
联合(多列)索引 (a,b,c) 一树多用,遵循最左前缀
空间索引 SPATIAL 地理数据类型

3.4 语法

sql 复制代码
-- 建表时指定
CREATE TABLE t (
    id INT PRIMARY KEY,
    name VARCHAR(20) UNIQUE,
    age INT,
    INDEX idx_age_name (age, name)          -- 联合索引
);

-- 单独创建
CREATE INDEX idx_name ON t(name);
ALTER TABLE t ADD INDEX idx_job_status (job, status);

-- 查看
SHOW INDEX FROM t;

-- 删除
DROP INDEX idx_name ON t;
ALTER TABLE t DROP INDEX idx_job_status;

3.5 聚簇索引与二级索引(必考)

  • 聚簇索引 :InnoDB 表按主键组织,B+ 树叶子节点直接存放整行数据------找到主键即找到数据。无主键时选第一个非空唯一索引,再没有则隐藏 row id。
  • 二级索引(辅助索引) :叶子节点存的是索引列值 + 主键值 。通过二级索引查到主键后,还要再走一遍聚簇索引取整行,即回表。
  • 覆盖索引 :查询列全部包含在所用索引内,无需回表(Extra 显示 using index)。这是"只查必要列、避免 SELECT *"的底层原因,也是索引优化的重要目标。

3.6 最左前缀法则与失效场景(必考)

联合索引 (a, b, c) 按 a→b→c 排序建树:查询从最左列开始、不跳过中间列才能命中;WHERE b=? AND c=?(缺 a)用不上;WHERE a=? AND c=? 只能用到 a 一段(8.0 索引跳跃扫描可部分缓解)。范围条件之后的列不再参与有序匹配:a=? AND b>? AND c=? 只用 (a,b),c 靠 ICP/过滤。

索引失效的典型场景:

  1. 在索引列上做运算/函数 :WHERE YEAR(dt)=2026、WHERE id+1=5(改成范围或等值原列)。
  2. 隐式类型转换 :字符串列用数字比较 WHERE varchar_col = 123(MySQL 把列转数字,索引失效;写 = '123' 即好)。
  3. LIKE 以 % 开头 :'%abc';'abc%'、'a%c' 仍可用。
  4. OR 连接的条件中有未建索引的列(整体退化为全表扫描)。
  5. NOT IN、!=、<>、IS NOT NULL 等:优化器认为无索引可用时会放弃(数据分布决定,不是绝对失效)。
  6. 未满足最左前缀(如上)。
  7. 优化器判断全表扫描更快(如命中比例过高、表很小)。

3.7 前缀索引与 EXPLAIN 验证

sql 复制代码
ALTER TABLE t ADD INDEX idx_email (email(12));    -- 取前 12 个字符
-- 用区分度选前缀长度:
SELECT COUNT(DISTINCT LEFT(email,12))/COUNT(*) FROM t;

每加一个索引都要用 EXPLAIN 验证效果;加完索引发现没提速,多半是写法触发了失效场景。


4. SQL 优化技巧

4.1 插入与批量

  • 批量插入一条 SQL 多组 VALUES,或 LOAD DATA INFILE(最快)。
  • 导入前先关二级索引、DISABLE KEYS,导入后重建。
  • 主键尽量自增顺序插入,减少 B+ 树页分裂。

4.2 查询书写

  • 只查需要的列 ,不滥用 SELECT *(减少 IO、便于覆盖索引)。
  • WHERE 中把区分度高的条件放前面(对优化器影响有限,但写法好习惯)。
  • 用 EXISTS 替代 IN 处理大子查询、用 IN 替代大量 OR(视数据量,用 EXPLAIN 验证)。
  • 避免在 WHERE 中对列运算,把计算挪到常量侧:WHERE dt >= '2026-01-01' 而非 WHERE DATE(dt)=...。
  • ORDER BY 尽量与索引顺序一致;GROUP BY 会隐式排序,8.0 已移除 GROUP BY ... ORDER BY NULL,需要无序时用 ORDER BY NULL 替代写法或评估排序成本。
  • 分页用"延迟关联"(见 2.4)。
  • JOIN 用小表驱动大表(MySQL 的 NLJ 本质如此,写 STRAIGHT_JOIN 前先测);确保连接列有索引。

4.3 结构与配置

  • 大表做垂直拆分 (冷热字段分表)与水平分库分表;单表经验阈值 500 万~2000 万行。
  • 合理冗余(反范式)减少联表。
  • 连接数 max_connections、缓冲池 innodb_buffer_pool_size(物理内存 50%~70%)等参数按需调整。
  • 读写分离、引入缓存(Redis)分流热点读。

5. 数据设计与多表关系

5.1 三大范式(设计基线)

  • 第一范式 1NF:字段原子性,不可再分(地址拆成省/市/街道/邮编)。
  • 第二范式 2NF :消除对主键的部分依赖------联合主键下,非主键列必须依赖整个主键,否则拆表。
  • 第三范式 3NF :消除传递依赖------非主键列不能依赖另一个非主键列(学生表里不放"学院电话")。

实际开发:先满足 3NF;为性能可反范式冗余,用空间换时间,配合一致性逻辑。

5.2 多表关系建模

关系 建法
一对一 1:1 外键放任意一侧(常拆热点/冷点字段,如用户与详情表)
一对多 1:N 外键放"多"的一方(部门→员工)
多对多 N:N 建中间表,存双方主键两个外键

6. 视图(View)

6.1 概念与价值

视图是虚拟表,只存查询定义不存数据(物化视图 MySQL 原生不支持)。价值:简化复杂查询、屏蔽表结构细节(表改名改列时业务 SQL 不变)、聚焦行列级权限安全。注意:视图本身不提升性能,底层仍是原查询。

6.2 语法

sql 复制代码
CREATE [OR REPLACE] VIEW v_emp_dept AS
SELECT e.name, d.dept_name FROM employee e JOIN dept d ON e.dept_id = d.id;

SHOW CREATE VIEW v_emp_dept;        -- 查看定义
DESC v_emp_dept;                    -- 查看结构
DROP VIEW [IF EXISTS] v_emp_dept;

SELECT * FROM v_emp_dept WHERE dept_name = '研发部';   -- 像表一样查

更新基表数据,视图结果随之变化(视图无独立数据)。

6.3 可更新性与 WITH CHECK OPTION

单表视图的增删改会作用到基表;含 DISTINCT、GROUP BY、聚合、JOIN 等的视图不可更新。

sql 复制代码
CREATE OR REPLACE VIEW v_dept_emp AS
SELECT * FROM employee WHERE dept_id = 1
WITH CHECK OPTION;    -- 通过视图插入/更新时,必须仍满足 dept_id=1,否则报错

LOCAL CHECK(默认)只校验本视图条件;CASCADED CHECK 连上游视图条件一起校验。


7. 编程能力:变量、流程、游标

7.1 变量

sql 复制代码
-- 系统变量
SELECT @@global.autocommit;                  -- 全局
SELECT @@session.tx_isolation;               -- 会话(@@ 前省略即 session)
SET SESSION sort_buffer_size = 4194304;      -- 修改会话变量

-- 用户变量(@ 开头,当前会话有效,set 任意语句中)
SET @a = 10, @b = 20;
SELECT @sum := @a + @b;
SELECT name FROM t LIMIT @offset, 10;        -- 典型:分页变量

-- 局部变量(存储过程/函数内 DECLARE,必须在 BEGIN 块开头声明)
DECLARE total INT DEFAULT 0;
SET total = 1;
SELECT COUNT(*) INTO total FROM employee;    -- INTO 赋值

7.2 流程控制

sql 复制代码
-- IF(存储过程内)
IF score >= 90 THEN SET @g = 'A';
ELSEIF score >= 60 THEN SET @g = 'B';
ELSE SET @g = 'C';
END IF;

-- CASE
SELECT name,
  CASE WHEN job = 'Manager' THEN salary * 2
       WHEN job = 'Salesman' THEN salary * 1.5
       ELSE salary END AS new_sal
FROM emp;

SELECT *, CASE job WHEN 'CLERK' THEN '文员' WHEN 'MANAGER' THEN '经理' ELSE job END FROM emp;

-- LOOP / LEAVE(相当于 break)
DECLARE i INT DEFAULT 1;
lbl: LOOP
    SET i = i + 1;
    IF i > 10 THEN LEAVE lbl; END IF;
END LOOP lbl;

-- WHILE / DO...WHILE / REPEAT...UNTIL
WHILE i <= 10 DO SET i = i + 1; END WHILE;
REPEAT SET i = i + 1; UNTIL i > 10 END REPEAT;

7.3 游标(Cursor)

对 SELECT 结果集逐行处理(本质是"结果集上的指针"):

sql 复制代码
DECLARE done INT DEFAULT FALSE;
DECLARE cur CURSOR FOR SELECT name FROM employee;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;   -- 取不到数据时置标志

OPEN cur;
read_loop: LOOP
    FETCH cur INTO v_name;
    IF done THEN LEAVE read_loop; END IF;
    -- 逐行处理 v_name ...
END LOOP;
CLOSE cur;

游标只能用在存储过程/函数中;大结果集慎用,性能差,能用集合化 SQL 就不要逐行。


8. 存储过程与存储函数

8.1 概念对比

存储过程 PROCEDURE 存储函数 FUNCTION
返回值 无(可用 OUT 参数带出) 必须有且仅有一个 RETURN
调用 CALL p() 嵌入 SQL:SELECT f(x)
典型用途 复杂业务流程(批量、报表) 计算并返回单值

价值:一次编译长期复用(提升速度)、降低网络往返、封装权限(用户可执行而无需表权限)、可移植。缺点:调试难、版本管理弱、业务逻辑散落库中,互联网实践中常放应用层。

8.2 语法要点(DELIMITER 必知)

sql 复制代码
DELIMITER $$            -- 改语句结束符,避免过程内分号提前截断

CREATE PROCEDURE p_sal(
    IN emp_id INT,                      -- IN 入参;OUT 出参;INOUT 双向
    OUT avg_sal DECIMAL(10,2))
BEGIN
    SELECT AVG(salary) INTO avg_sal FROM employee WHERE dept_id = emp_id;
END$$

DELIMITER ;
CALL p_sal(1, @s);
SELECT @s;

CREATE FUNCTION f_year_bonuses(base INT) RETURNS INT
DETERMINISTIC                           -- 函数必须声明特性,否则 binlog 开启时报错
BEGIN
    DECLARE i INT DEFAULT 1; DECLARE total INT DEFAULT 0;
    WHILE i <= 3 DO
        SET total = total + base; SET i = i + 1;
    END WHILE;
    RETURN total;
END$$
SELECT f_year_bonuses(5000);

管理语句:

sql 复制代码
SHOW PROCEDURE STATUS;              -- 列出所有过程(Db/Name)
SHOW CREATE PROCEDURE p_sal;        -- 查看定义
DROP PROCEDURE [IF EXISTS] p_sal;   -- DROP FUNCTION 同理

权限不足时检查 log_bin_trust_function_creators(开 binlog 时创建函数需要 SUPER 或该参数置 1)。


9. 触发器(Trigger)

9.1 概念与组成

基于事件 + 时机自动执行的 SQL 集合:事件 = INSERT/UPDATE/DELETE;时机 = BEFORE/AFTER;粒度 = FOR EACH ROW 行级(MySQL 仅支持行级)。典型用途:审计日志、强制复杂约束、自动衍生值维护。

sql 复制代码
DELIMITER $$
CREATE TRIGGER trg_emp_before_ins
BEFORE INSERT ON employee            -- 时机 + 事件 + 表
FOR EACH ROW
BEGIN
    IF NEW.salary < 0 THEN SET NEW.salary = 0; END IF;
    SET NEW.created_by = CURRENT_USER();
END$$
DELIMITER ;
  • NEW:新行(INSERT/UPDATE 后的值;UPDATE 中可改 NEW 实现数据修正)。
  • OLD:旧行(DELETE/UPDATE 前的值,INSERT 时不可用)。
  • BEFORE 校验/改写数据;AFTER 记录、联动(如写入审计表)。

9.2 管理

sql 复制代码
SHOW TRIGGERS;                        -- 可 LIKE '表名' / FROM 库名 过滤
DROP TRIGGER IF EXISTS trg_emp_before_ins;

⚠️ 坑:触发器里不能再操作触发它的那张表 (自引用限制,报错 "Can't update table ... in function call"),需要绕行应用层或函数封装;触发器隐蔽性强,团队协作中建议在文档/命名上明确(如 tri_表_时机_事件)。


10. 事务底层:锁与隔离

10.1 并发事务三大问题回顾

脏读(读到未提交)、不可重复读(同行两次读不同,因 UPDATE)、幻读(两次查询行数不同,因 INSERT)。隔离级别由低到高:READ UNCOMMITTED / READ COMMITTED / REPEATABLE READ(MySQL 默认) / SERIALIZABLE,级别越高越安全、并发越差。

10.2 锁的分类

维度 类型
粒度 全局锁(FTWRL,全库只读做逻辑备份)、表级锁、行级锁
模式 共享锁 S(读)、排他锁 X(写);SELECT ... LOCK IN SHARE MODE / FOR SHARE、FOR UPDATE
姿态 乐观锁(版本字段 CAS,应用层思想)、悲观锁(FOR UPDATE)
意图 意向锁 IS/IX:表级"占位声明",加速表锁判断

表级锁细节 :表锁(阻塞增删改查)、LOCK TABLES ... READ/WRITE 显式锁、元数据锁 MDL(DML 持 MDL 读、DDL 持 MDL 写------DDL 卡在长事务前多为 MDL 等待)、自动锁定(配合 INSERT ... AUTO_INCREMENT)。

InnoDB 行锁三种算法(RR 级别下):

  1. Record Lock:锁具体记录行。
  2. Gap Lock:锁记录间空隙,只阻止插入、不互斥,解决幻读。
  3. Next-Key Lock:Record + Gap(左开右闭区间),InnoDB 默认加锁单位。

⚠️ 行锁只对索引生效 :不加索引条件或优化器放弃索引时,升级为锁扫描到的所有行/间隙,近似表锁。死锁:两个事务互相等待,innodb_deadlock_detect 会回滚代价小的一方(错误码 1213),业务需重试。

10.3 MVCC 多版本并发控制(RR 的核心)

  • 目标:读写不互相阻塞------读快照不加锁,写当前版本加锁。
  • 三要素:
    1. 隐藏字段:每行带事务 ID(trx_id)与回滚指针(roll_pointer)。
    2. undo log 版本链:修改前旧值沿链保存,形成历史版本。
    3. ReadView 读视图:记录快照时刻的活跃事务列表(m_ids)、min/max_trx_id、创建者 id。读取时沿版本链找"对自己可见"的版本。
  • 可见性判断要点:trx_id = 创建者 → 可见;不在 m_ids(已提交)→ 可见;≥ max_trx_id(快照后才开启)→ 可见;在 m_ids 内 → 不可见,沿链上溯。
  • RC 与 RR 的本质区别:RC 每次 SELECT 生成新 ReadView(会读到别的事务已提交的新值→不可重复读);RR 只在事务第一次 SELECT 生成一次(全程同一快照→可重复读)。
  • MVCC 解决"快照读"(普通 SELECT)的不可重复读与大部分幻读;"当前读"(FOR UPDATE、UPDATE、SELECT 走锁)由 Next-Key Lock 解决。

10.4 长事务危害

undo log 膨胀版本链变长、锁持有时间长、连接与 ID 资源耗尽。上线前用 SELECT * FROM information_schema.innodb_trx WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 60; 抓长事务。


11. MySQL 日志体系

日志 层 作用
错误日志 error log server 启动/运行报错,排障第一入口
慢查询日志 slow log server 性能分析(见第 2 章)
二进制日志 binlog server 归档型 :记录所有变更 DDL/DML 的语句(不记录 SELECT),用于主从复制 与数据恢复(任意时间点)
回滚日志 undo log InnoDB 回滚型:保存旧版本,构成 MVCC 版本链、支撑事务回滚
重做日志 redo log InnoDB 环形物理日志:记录页的修改,保证崩溃后数据不丢(WAL)

两阶段提交(2PC):更新时先写 redo log(prepare)→ 写 binlog → 提交 redo log(commit)。为什么需要:保证 redo(实例恢复)与 binlog(归档/主从)两份日志逻辑一致------宕机恢复后主从不因" redo 有 binlog 无"而数据分叉。

刷盘策略 innodb_flush_log_at_trx_commit:1 最安全(每次提交刷盘),2 性能较好且宕 OS 不丢,0 仅每秒刷。binlog 刷盘 sync_binlog 同理,双 1 为金融级配置。


12. 备份与恢复

12.1 分类

  • 物理备份:直接拷数据文件(冷备需停服;热备用 Percona XtraBackup)。
  • 逻辑备份:导出 SQL 语句(mysqldump),可跨版本、可细粒度挑选。
  • 全量 / 增量;冷 / 热 / 温;恢复目标:整库、指定表、任意时间点(binlog 重放)。

12.2 mysqldump 常用

bash 复制代码
mysqldump -u root -p db_name > db.sql                 # 备份单库
mysqldump -u root -p --all-databases > all.sql        # 所有库(-B 指定多库)
mysqldump -u root -p db_name tbl1 tbl2 > t.sql        # 指定表(-T 可导出为数据文件+建表)
mysqldump -u root -p --single-transaction --master-data=2 db > db.sql   # InnoDB 一致性热备 + 记录 binlog 位点(主从/时间点恢复用)
mysql -u root -p db_name < db.sql                      # 恢复

备份策略口诀:定期全备 + 持续 binlog ,恢复 = 最近全备 + 重放其后 binlog。逻辑备份适合中小库;大库用物理热备工具,并务必演练恢复(没验证过的备份等于没有备份)。


13. 附录:配置管理与常见报错

13.1 配置文件与优先级

  • Linux:/etc/my.cnf(全局)、~/.my.cnf;Windows:my.ini。
  • 优先级:mysqld --参数 > mysqld_safe --参数 > etc/my.cnf > login shell。
  • 关键参数:datadir、port、max_connections、innodb_buffer_pool_size、character-set-server=utf8mb4、大小写敏感 lower_case_table_names(Linux 默认区分,建库前定好)。

13.2 高频报错速查

报错 原因与处理
1062 Duplicate entry 唯一/主键冲突
1213 Deadlock found 死锁,业务重试;缩短事务、统一加锁顺序
1205 Lock wait timeout 锁等待超时,查 innodb_trx / processlist 找持锁方
1242 Subquery returns more than 1 row 标量子查询返回多行,改 IN 或加 LIMIT
ERROR 2002/10061 无法连接 服务未启动 / 端口 / bind-address 配置
外键报错 150/1452 引用列非主键唯一,或从表数据违反约束
函数创建报 binlog 错误 SET GLOBAL log_bin_trust_function_creators = 1 或补特性声明

13.3 进阶方向

  • 高可用:主从复制原理(binlog→relay log→SQL 线程)、GTID、MHA/InnoDB Cluster、读写分离中间件
  • 分库分表:水平拆分路由(ShardingSphere)、全局 ID(雪花算法)
  • 新特性:窗口函数(8.0 OVER())、CTE(WITH)、JSON 类型与函数、直方图、不可见索引、DESC 索引、information_schema / performance_schema 深度使用
  • 内核向:B+ 树页结构、Change Buffer、Doublewrite、自适应哈希
相关推荐
yma161 小时前
从零搭建 P2P 聊天室:yma16.cloud 在线工具实战
前端·1024程序员节
小码哥(^_^)1 小时前
人力资源面试题集1
eclipse·1024程序员节
染指11101 小时前
155.Agent-LangGraph-节点级重试策略
人工智能·langchain·1024程序员节·agents
labview_自动化1 小时前
Labview动态加载类
1024程序员节
Yxj-52113141 小时前
JS中的内存管理是如何工作的?
1024程序员节
归-途1 小时前
C# 实现扫描件自动分栏切图
1024程序员节
Oiiouui1 小时前
Godot-GridGame架构数据层篇
架构·godot·1024程序员节
java_nnnn1 小时前
Redis 核心特性与应用场景:从底层原理到分布式系统应用
数据库·redis·1024程序员节
Random Glow1 小时前
一条 SQL 从输入到返回,中间经历了什么
数据库·后端·mysql·性能优化·innodb·1024程序员节