索引“失效”90%是优化器未选择而非丢失,应先用explain查看执行计划;show index返回空说明索引缺失而非失效;navicat导入csv/excel/.nb3时默认不带索引,需手动补全create index语句。
索引“失效”90%是优化器没选,不是真丢了——先跑 explain 看执行计划,再决定要不要重建。
SHOW INDEX FROM table_name 返回空,说明索引根本没建上
这不是失效,是缺失。Navicat 导入时默认不带索引,尤其用 CSV/Excel 或 .nb3 备份时,CREATE INDEX 语句压根没执行。
- 检查导入向导里「对象类型」是否勾选了「索引」——很多用户只勾了「表」和「视图」
- 打开你的备份文件(如
backup.sql),搜索CREATE INDEX或KEY,确认是否存在 - 如果是
.nb3格式,它不存 DDL,还原后必须手写CREATE INDEX补全,Navicat 的任何「修复」功能都无效 - 别用图形界面点「设计表 → 索引」批量加——它常漏写
USING BTREE、大小写错位,或把UNIQUE KEY错写成UNIQUE
EXPLAIN SELECT 显示 key 为 NULL,但 SHOW INDEX 有结果
索引存在,只是优化器拒绝使用。最常见原因是统计信息过期,尤其大批量导入后,InnoDB 不会自动刷新采样值。
- 优先执行
ANALYZE TABLE your_table_name;——毫秒级、无锁、只更新统计信息,比OPTIMIZE TABLE轻量得多 - 批量修复可用:
SELECT CONCAT('ANALYZE TABLE `', table_name, '`;') FROM information_schema.TABLES WHERE table_schema = 'your_db' AND engine = 'InnoDB'; - Navicat 图形界面里的「维护 → 重新优化表」实际执行的是
OPTIMIZE TABLE,非必要不用,它会重建整个表 - MySQL 8.0+ 可对特定列强制细粒度采样:
ANALYZE TABLE your_table_name UPDATE HISTOGRAM ON column_name;
索引存在、统计也更新了,但还是走全表扫描
这时问题不在 Navicat,而在查询本身或索引设计。优化器的判断是对的,只是你没意识到。
- 检查
WHERE是否满足最左前缀:比如索引是(status, created_at),但查询只写了WHERE created_at > '2024-01-01',该索引完全无法启动 - 查隐式转换:字段是
VARCHAR,却写成WHERE id = 123(没加引号),MySQL 强转类型导致索引失效 - 小表(几百行)走
type: ALL是合理行为——优化器算出来全表扫描比回表更快,不是 bug - Navicat ≤16.0 版本解析
EXPLAIN输出时可能丢掉key字段,建议升级到 17+,或用命令行执行EXPLAIN FORMAT=JSON SELECT ...
真正容易被忽略的,是那些藏在配置里的静默陷阱:比如还原时勾了 Ignore AUTO_INCREMENT,或字符集不匹配(源 utf8mb4 → 目标 latin1)导致 DDL 解析失败后直接跳过后续索引语句——它不报错,也不提示,就默默建了个裸表。











