索引缺失的三大主因:SQL文件无索引语句、用户缺ALTER权限、导入跳过索引维护;对应排查:检查SHOW CREATE TABLE、SHOW GRANTS,执行OPTIMIZE/ANALYZE TABLE或清理DEFINER。
SHOW INDEX FROM 显示索引缺失,不是导入失败的错觉,而是索引根本没建上去——最常见原因就两个:SQL文件本身不含索引语句,或者当前 MySQL 用户缺 ALTER 权限。很多用户用 mysqldump 时加了 --no-create-info 或只导数据(比如用 --no-create-db --skip-triggers 过度精简),结果 sql 文件只有 insert,没有 create table 和索引定义。
SHOW CREATE TABLE table_name 输出里有没有 KEY、UNIQUE KEY、PRIMARY KEY 等行mysqldump -u user -p db_name table_name > backup.sql —— 默认就带结构CREATE INDEX idx_col ON table_name(col);
phpMyAdmin 图形界面点“创建索引”或执行 CREATE INDEX 语句时,若当前用户缺少 ALTER(MySQL 5.7+ 隐含 INDEX)权限,MySQL 直接拒绝,报错类似 ERROR 1142: INDEX command denied,但 phpMyAdmin 有时只显示空白或超时,不弹具体错误。
SHOW GRANTS FOR 'user'@'host'; —— 看输出里有没有 GRANT ALTER ON `db`.*
GRANT ALTER ON `db_name`.`table_name` TO 'user'@'host'; FLUSH PRIVILEGES;
'user'@'localhost' 和 'user'@'%' 是不同账号,别写错大批量 INSERT(尤其 phpMyAdmin 导入默认模式)会跳过索引页合并与 B+ 树重组,导致索引虽存在但严重碎片化,EXPLAIN 显示 key 非空却 rows 极大,查询仍走全表扫描。
OPTIMIZE TABLE table_name; —— InnoDB 下等价于重建所有索引 + 更新统计信息ANALYZE TABLE table_name;,否则优化器可能继续用旧统计OPTIMIZE 临时需要 2 倍表大小空间SQL 文件里混着 CREATE VIEW 且含 DEFINER,而目标库没该用户,MySQL 在解析阶段就卡住,后续的 CREATE INDEX 根本没机会执行——错误日志里常出现 ERROR 1449,但 phpMyAdmin 可能只报“脚本中断”。
sed -E "s/DEFINER=[^ ]+//g" dump.sql > clean.sql
DEFINER=`xxx`@`yyy` 子句(保留 SQL SECURITY)SET sql_mode = '';,避免严格模式下字段类型不匹配导致中途退出SHOW INDEX 和 SHOW GRANTS 多跑一遍,比反复重试快得多。