performance_schema.data_locks能实时反映事务持锁状态,加锁即可见;但需先启用相关instrument,且其INDEX_NAME和LOCK_DATA精度依赖元数据准确性,是优化器Cost Model智能选索引的底层可观测支撑。

performance_schema.data_locks 能实时看到事务持锁状态,不是“等冲突才上报”,而是“加锁即可见”——这是 MySQL 8.0 索引管理更智能的底层支撑,但真正体现“智能化”的地方不在锁本身,而在优化器如何理解、选择和验证索引。
Cost Model 让优化器会“算账”,不是“拍脑袋”选索引
5.7 的优化器看到 WHERE a = ? AND b > ?,只要 idx_a 存在就走它;8.0 会基于统计信息估算走 idx_a、idx_b 或全表扫描的 I/O 和 CPU 成本,再挑总代价最低的。
- 前提是
ANALYZE TABLE必须跑过,否则统计信息陈旧,Cost Model 反而选错——升级后第一件事就是执行这个命令 -
EXPLAIN FORMAT=TREE能直接看到每个节点的预估cost值,5.7 不支持该语法 - 若发现某条 SQL 升级后变慢,先查
SELECT @@optimizer_switch LIKE '%cost_model=on%',再确认统计信息是否更新
函数索引和降序索引让“表达式”和“排序方向”真正可索引化
5.7 对 UPPER(name) 或 ORDER BY a DESC 无能为力,只能靠冗余列或忍受 filesort;8.0 把它们变成可落地的物理索引结构。
- 函数索引必须配合
STORED生成列:ALTER TABLE t ADD COLUMN name_upper VARCHAR(255) GENERATED ALWAYS AS (UPPER(name)) STORED,再对name_upper建普通索引 - WHERE 条件必须字面一致:
WHERE UPPER(name) = 'ABC'才能命中,WHERE name = 'abc'或WHERE UPPER(name) LIKE '%abc%'都不行 - 降序索引
INDEX (a DESC, b ASC)在 5.7 中会被忽略(SHOW CREATE TABLE显示仍为升序),8.0 才真正按物理降序存储,ORDER BY a DESC, b ASC可免 filesort
隐藏索引让索引变更从“高危操作”变成“灰度实验”
以前删索引像开盲盒,怕某条报表 SQL 突然变慢;现在可以先设为不可见,观察一周再决定是否删。
-
ALTER TABLE t ALTER INDEX idx_name INVISIBLE后,优化器默认不选它,但索引仍在后台维护、占磁盘空间 - 主键和第一个唯一索引(当表无主键时)不能设为不可见,MySQL 会报
ERROR 3092 - 想临时验证该索引效果,需手动开启:
SET SESSION optimizer_switch = "use_invisible_indexes=on" - 5.7 不识别
INVISIBLE语法,建表或修改直接报ERROR 1064
performance_schema.data_locks 显示的 INDEX_NAME 和 LOCK_DATA 越准,优化器越能判断哪个索引实际参与了锁竞争;而 ANALYZE TABLE 更新的统计信息越新,Cost Model 的估算才越可靠。没有这些底层可观测性支撑,“智能”只是纸面逻辑。


















