连接器先校验身份再查权限表,按user→db→tables_priv→columns_priv逐级检查;解析器阶段报错说明语句未通过词法和语法分析;优化器基于成本估算选索引,FORCE INDEX非绝对生效;MySQL 8.0已彻底移除查询缓存。

连接器先校验身份,再查权限表
你执行 mysql -u root -p 后输入密码,连接器干的不是“连上就完事”,而是立刻查 mysql.user 表确认账号是否存在、密码哈希是否匹配;通过后,再按 user → db → tables_priv → columns_priv 顺序逐级查权限。哪怕你只查一张表的某个字段,只要 columns_priv 里没开对应列的 SELECT 权限,就会报 ERROR 1142 (42000): SELECT command denied to user,而不是语法错误。
常见踩坑点:
- 用
SHOW PROCESSLIST能看到当前所有连接的Id和User,但看不到具体权限——权限是会话级缓存的,改了mysql库的权限表后,必须执行FLUSH PRIVILEGES或让客户端重连才生效 -
wait_timeout默认 8 小时,长连接空闲太久会被自动断开,应用层若没做重连逻辑,就会突然报MySQL server has gone away - 权限验证失败时,错误信息里带
@'host'(比如'root'@'192.168.1.100'),说明 MySQL 是按「用户名+来源 IP」组合鉴权的,不是单看用户名
解析器报错 = 语句根本没进优化器
当你写错 SELECT * FROM users WHERE id = 123; 成 SELCT * FROM users WHERE id = 123;,或者查一个不存在的列 SELECT phone FROM users;,错误发生在解析器阶段——它做完词法分析(拆出关键字、标识符)和语法分析(检查结构是否符合 SELECT ... FROM ... WHERE ... 规则)后直接报错,根本不会走到优化器或执行器。
这意味着:
-
EXPLAIN对这种语句无效,执行就报错,没法看执行计划 - 语法检查顺序严格:
SELECT → FROM → JOIN → ON → WHERE → GROUP BY → HAVING → UNION → ORDER BY → LIMIT,漏写FROM或把WHERE写在GROUP BY前面,都会被解析器拦下 - 大小写和空格敏感:在 MySQL 5.7 及以前,
select * from t和SELECT * FROM t是两个不同缓存 key(虽然 8.0 已删缓存,但解析器仍按字面值比对)
优化器选索引不认你写的 FORCE INDEX?正常
你加了 FORCE INDEX (idx_created_at),但 EXPLAIN 显示还是走全表扫描?不是 MySQL 忽略你,而是优化器在 ANALYZE TABLE 统计信息基础上做了成本估算:如果 created_at 索引选择性差(比如只有 3 个不同值)、表又小(Rows 显示才几百行),它判断走索引回表反而比直接扫更快。
实操建议:
- 用
SHOW TABLE STATUS LIKE 'orders'查Rows和Data_length,再用SELECT COUNT(DISTINCT status) / COUNT(*) FROM orders算选择性,低于 0.01 就别指望它用这个字段索引 -
FORCE INDEX是绕过优化器的“硬指令”,但数据量突增后可能从加速变拖慢,线上慎用 - 真正可控的是建好复合索引:比如
WHERE status = ? ORDER BY created_at DESC,优先建(status, created_at)而非单列索引
MySQL 8.0 起,查询缓存已彻底消失
别再查 query_cache_size 或设 query_cache_type = 1——MySQL 8.0 把整个查询缓存模块(包括内存管理、失效逻辑、所有相关变量)全删了。你升级到 8.0 后如果还依赖缓存,要么换应用层缓存(Redis),要么靠 InnoDB 缓冲池(innodb_buffer_pool_size)扛热数据。
为什么删?因为:
- 缓存 key 是 SQL 字符串全匹配,
SELECT * FROM t和SELECT * FROM t(多两个空格)就是两个缓存项 - 一张表任何
INSERT/UPDATE/DELETE,所有涉及该表的缓存全部失效,写多读少场景下命中率趋近于 0 - 多线程争抢缓存锁,高并发时反而成为瓶颈
现在真正的“缓存”只剩两层:InnoDB 的数据页缓存(由 innodb_buffer_pool_size 控制),和操作系统的 page cache——它们不认 SQL,只认磁盘块,更底层也更稳定。










