为什么面试官总爱问 SQL 执行流程?
因为这不是考你背流程图,而是借流程判断你有没有「数据库底层意识」——比如写一条
SELECT * FROM users WHERE age > 25 ORDER BY name LIMIT 10,你是否下意识想到:它会不会走索引?优化器会不会把
ORDER BY推到存储引擎层做?执行器在调用 InnoDB 前有没有校验权限?这些细节直接暴露你平时是“写完能跑就行”,还是真会看
EXPLAIN、调慢查、改索引。
MySQL 8.0 后必须跳过的坑:查询缓存
几乎所有老面经还写着“先查查询缓存”,但 MySQL 8.0 已彻底移除
query_cache_type和相关参数。继续按旧流程答,等于暴露你没验证过环境版本。 MySQL 5.7 及以前:缓存键是完整 SQL 字符串(区分空格、大小写),表一更新,所有关联缓存全失效 → 高并发写多场景下几乎无用 MySQL 8.0+:该模块代码已删除,
SHOW VARIABLES LIKE 'query_cache%'查不到任何结果 替代方案不是“等缓存”,而是:
CREATE INDEX idx_age_name ON users(age, name)让排序 + 过滤一步到位
执行器阶段最容易被忽略的权限检查
很多人以为权限只在连接时校验一次,其实执行器在真正调存储引擎前还会再查一遍——而且用的是连接建立时读取的快照权限,不是实时权限表。
现象:你用 root 给用户test_user新增了
SELECT权限,但已有连接仍报
ERROR 1142 (42000): SELECT command denied原因:执行器读的是连接初始化时从
mysql.user表加载的权限缓存,不会动态刷新 解法:
FLUSH PRIVILEGES仅更新内存权限快照;更稳妥的是让应用重连,或使用连接池的
validationQuery主动探测
更新语句比查询多出的关键两步:redo log + binlog 两阶段提交
面试问“update 为什么比 select 慢”,不能只答“要写磁盘”。核心在于 InnoDB 的崩溃恢复机制依赖两日志协同:
1. 执行器调用 InnoDB,写入数据页并记入 redo log(prepare 状态) 2. 执行器写入 server 层的 binlog 3. 执行器通知 InnoDB 将 redo log 改为 commit 状态
这三步缺一不可。如果第 2 步失败(如磁盘满),事务回滚;如果第 3 步失败(如 mysqld 崩溃),重启后 MySQL 会检查 binlog 是否完整,决定是提交还是回滚 —— 这就是为什么主从复制靠 binlog,而单机崩溃恢复靠 redo log。
真正容易被绕晕的点是:
binlog是 Server 层日志,不认事务;
redo log是 InnoDB 层日志,只管物理页变更。两者不在同一层,必须靠两阶段提交对齐状态。
