join变慢或全表扫描主因是关联字段collation不一致,需用information_schema.columns核对并alter table显式同步character set与collate,同时确保客户端连接正确声明utf8mb4及对应collate。

查询变慢或全表扫描,先查JOIN字段的COLLATION是否一致
EXPLAIN 显示 type: ALL 或 Using join buffer,但单表查询很快,大概率是关联字段字符集或排序规则不一致。MySQL 在 JOIN 时要求两边字段的 COLLATION 可比性一致,哪怕都是 utf8mb4,若一边是 utf8mb4_0900_as_cs、另一边是 utf8mb4_unicode_ci,也会触发隐式转换,索引直接失效。
检查方法很简单:
- 执行
SHOW CREATE TABLE t1和SHOW CREATE TABLE t2,对比关联字段(如t1.user_id和t2.uid)定义里的CHARACTER SET和COLLATE - 更直接:查
INFORMATION_SCHEMA.COLUMNS:SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME IN ('t1', 't2') AND COLUMN_NAME IN ('user_id', 'uid');
注意:别只看库级默认值(character_set_database),它不影响已有表;真正起作用的是字段定义里写的那部分。
ALTER TABLE MODIFY 要连 CHARACTER SET 和 COLLATE 一起改
只写 MODIFY COLUMN name VARCHAR(50) CHARACTER SET utf8mb4 是无效的——它不会改 COLLATE,而 MySQL 比较时实际依赖的是排序规则。必须显式带上 COLLATE,且目标值要和关联表字段完全一致。
正确写法示例:
ALTER TABLE t2 MODIFY uid VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs;
关键点:
- 先确认目标表字段当前的
COLLATION_NAME(用上面的INFORMATION_SCHEMA查询),再选匹配项,别硬套utf8mb4_unicode_ci - 如果字段有索引,
MODIFY会重建索引,大表耗时明显;线上务必低峰期操作 - 含外键或全文索引的表,
MODIFY可能失败,需提前处理约束
存储过程里传参的 COLLATE 写法必须收敛到列的实际规则
在存储过程中用 NAME_CONST() 或拼接字符串做条件时,如果显式写了 _utf8mb4'xxx' COLLATE utf8mb4_unicode_ci,但对应列实际是 utf8_unicode_ci 或 utf8mb4_0900_as_cs,优化器就会拒绝走索引。
安全写法只有三类:
- 省略
COLLATE:WHERE ref_id = _utf8mb4'c37e32fc-b3b5-11ec-befc-02447a44a47c',让 MySQL 按列定义自动推导 - 显式对齐列的
COLLATE:WHERE ref_id = _utf8mb4'...' COLLATE utf8mb4_0900_as_cs(前提是列确实是这个) - 统一用连接级默认规则:
SET NAMES utf8mb4 COLLATE utf8mb4_0900_as_cs后再执行查询
切忌混用:比如列是 utf8,参数却用 _utf8mb4 + COLLATE,既触发转换又不兼容。
客户端连接不配 utf8mb4,前面全白干
库、表、字段、SQL 全都改对了,但应用连上来时没声明字符集,照样出问题。MySQL 不从服务端配置反推连接编码,它只认连接初始化阶段的声明。
必须确保三点同时满足:
- 连接串里加
?charset=utf8mb4(JDBC、PHP PDO 等通用) - 连接建立后立刻执行
SET NAMES utf8mb4 COLLATE utf8mb4_0900_as_cs(或对应实际使用的COLLATE) - 验证会话变量:
SELECT @@character_set_client, @@character_set_connection, @@character_set_results;三个都得是utf8mb4
漏掉任意一个,WHERE name = '中文' 这类查询就可能被转码,索引失效或结果错乱——而且这种问题在线上往往只在特定输入下才暴露,排查成本极高。











