还原后索引没建上,先执行SHOW INDEX FROM table_name确认是否为空;若为空,说明索引缺失而非失效,需手动用CREATE INDEX等语句重建,并执行ANALYZE TABLE更新统计信息。
还原后索引没建上,先看 SHOW INDEX 输出是否为空
navicat 还原时如果跳过索引创建(比如选了“仅数据”模式、sql 文件里没带 create index 语句、或备份导出时禁用了 ddl),表结构里就只有列,没有索引。这不是“失效”,是压根没建。
执行:SHOW INDEX FROM table_name; —— 如果结果为空或只返回主键(Key_name: PRIMARY),说明索引确实缺失。
- 检查 Navicat 还原对话框里的「对象类型」是否勾选了「索引」;默认有时只勾「表」「视图」
- 打开你用的 .sql 备份文件,搜索
CREATE INDEX或KEY,确认语句是否存在 - 如果是 nb3 格式备份,它不包含完整 DDL,还原后必须手动补索引
手动重建索引前,先确认存储引擎和权限
MySQL 中,ALTER TABLE ... ADD INDEX 在 MyISAM 上会锁全表,在 InnoDB 上默认走 ALGORITHM=INPLACE,但前提是没触发退化条件。
- 查引擎:
SHOW CREATE TABLE table_name;,确认是ENGINE=InnoDB - 查权限:
SHOW GRANTS FOR CURRENT_USER;,确保含INDEX权限,缺就让 DBA 执行:GRANT INDEX ON db_name.table_name TO 'user'@'%'; - 避免用 Navicat 的图形化「设计表 → 索引」界面批量加——它可能拼错语法(比如漏写
USING BTREE或列名大小写不匹配)
用标准 SQL 一条一条加索引,别依赖 Navicat 自动生成
Navicat 的「快速修复表」或「维护 → 修复」功能对缺失索引无效,它只修损坏索引,不补漏建的。
直接手写 SQL 最可靠:
CREATE INDEX idx_user_status ON users(status, created_at) USING BTREE; CREATE UNIQUE INDEX uk_email ON users(email) USING BTREE;
- 联合索引列顺序必须贴合查询习惯,比如常查
WHERE status = ? AND created_at > ?,那就按(status, created_at)建 - 如果表很大,加索引期间会阻塞写入,建议在低峰期执行;加完立刻验证:
EXPLAIN SELECT * FROM users WHERE status = 'active'; - 不要用
ALTER TABLE ADD INDEX代替CREATE INDEX—— 后者语义更清晰,且 MySQL 8.0+ 对两者的锁行为有细微差异
统计信息过期会让“已建索引”看起来像失效
即使索引存在,EXPLAIN 显示全表扫描,大概率是优化器统计信息陈旧,误判索引无用。
- 强制更新:
ANALYZE TABLE users;(MySQL)或VACUUM ANALYZE users;(PostgreSQL) - 特别注意:Navicat 还原后如果跳过了
ANALYZE步骤(很多备份脚本不带),就必须手动补 - 如果单表行数超千万,
ANALYZE TABLE可能采样不足,可加参数:ANALYZE TABLE users UPDATE HISTOGRAM ON status, email;(MySQL 8.0+)
真正容易被忽略的是:nb3 备份 + 还原 + 忘记 ANALYZE,三连击下索引“存在但不用”,比漏建还难排查。


















