慢查询主因是join字段collation_name不一致导致索引失效;需用show full columns或查询information_schema确认实际排序规则;alter table modify须同时指定character set和collate;还需统一collation_connection。

慢查询不是因为数据量大,而是MySQL在JOIN时发现两边字段的COLLATION_NAME不一致,直接放弃索引——哪怕都建了索引,EXPLAIN里也会显示type: ALL或key: NULL。
怎么快速确认是COLLATION不一致?
别查SHOW CREATE DATABASE里的默认值,它对已有字段没影响。真正起作用的是字段定义里写的那部分。
- 用
SHOW FULL COLUMNS FROM t1 LIKE 'user_id'查Collation列值,注意utf8mb4_0900_as_cs和utf8mb4_unicode_ci虽同属utf8mb4,但不可比 - 更稳妥:一次性比对多张表,执行
SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME IN ('t1','t2') AND COLUMN_NAME IN ('uid','ref_id'); - 只要
COLLATION_NAME不完全相同,哪怕CHARACTER_SET_NAME都是utf8mb4,JOIN就可能失效
ALTER TABLE MODIFY必须同时指定CHARACTER SET和COLLATE
只写ALTER TABLE t2 MODIFY uid VARCHAR(50) CHARACTER SET utf8mb4是无效操作——它不会改COLLATE,而MySQL比较时实际依赖的是排序规则。
- 正确写法:
ALTER TABLE t2 MODIFY uid VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs; - 目标
COLLATE必须跟关联字段完全一致,别硬套utf8mb4_unicode_ci,先用SHOW FULL COLUMNS确认当前值 - 字段有索引时,
MODIFY会重建索引;大表务必低峰期操作,否则锁表时间长 - 含外键或全文索引的表,
MODIFY可能失败,需提前DROP FOREIGN KEY或处理约束
改完表结构,查询还是慢?检查连接层collation_connection
就算所有字段COLLATION全统一了,如果应用连上来时@@collation_connection是utf8mb4_unicode_ci,而字段是utf8mb4_0900_as_cs,MySQL仍会在解析WHERE name = 'xxx'时做隐式转换,索引照样失效。
- 验证当前连接状态:
SELECT @@collation_connection; - 应用连接串里要显式声明
charset=utf8mb4并匹配目标COLLATE,例如JDBC加connectionCollation=utf8mb4_0900_as_cs -
SET NAMES utf8mb4 COLLATE utf8mb4_0900_as_cs;可临时修复,但必须在每次连接初始化时执行
真正容易被忽略的是:外键、UNION字段、存储过程传参这些地方也受COLLATION影响,它们不显式出现在JOIN语句里,但照样触发字符串比对,一不注意就崩。











