MyISAM的FULLTEXT索引无法直接迁移至InnoDB,必须重建并调整配置;二者分词逻辑、最小词长、停用词表及中文支持均不兼容,需验证分词结果与索引实际生效情况。

MyISAM 的 FULLTEXT 索引不能直接“迁移”到 InnoDB——必须重建,且行为不兼容,不验证就上线大概率查不到结果。
查原表是否真用了 FULLTEXT 索引
别信建表语句或文档,直接查当前生效的索引。MyISAM 表可能建了 FULLTEXT 但长期不用,InnoDB 迁移后却因配置没调导致查询全空。
- 执行
SHOW INDEX FROM your_table WHERE Key_name = 'FULLTEXT',有结果才说明实际存在 - 用
SHOW CREATE TABLE your_table确认索引字段和停用词设置(如ft_stopword_file是否自定义) - 注意:MyISAM 全文索引对中文默认分词失败,业务若依赖中文搜索,InnoDB 同样不支持,得提前换方案
InnoDB 全文索引的三个硬性行为差异
InnoDB 的 FULLTEXT 不是 MyISAM 的“平替”,底层实现、分词逻辑、最小词长都不同,相同 SQL 可能返回空或乱序。
-
innodb_ft_min_token_size默认是 3(MyISAM 是 4),短词(如“AI”“OK”)在 InnoDB 中会被索引,MyISAM 中被忽略 - 停用词表路径和内容不同:
innodb_ft_server_stopword_table或innodb_ft_user_stopword_table需显式指定,否则用内置英文停用词 - 分词器不兼容:MyISAM 用
myisam_ftdump查分词,InnoDB 必须用INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE+INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE查,工具链断层
验证时别只跑 MATCH() AGAINST(),要对比分词结果
光看 SQL 能不能执行、有没有报错,掩盖不了语义丢失。真正要验证的是“哪些词被索引了”“哪些词被过滤了”。
- 对同一文本,分别在 MyISAM 和 InnoDB 表上执行:
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE WHERE MATCH(text_column) AGAINST('关键词' IN NATURAL LANGUAGE MODE) - 用
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD检查停用词是否覆盖业务高频词(如“的”“了”“app”) - 如果业务强依赖中文,必须启用 ngram 解析器:
SET GLOBAL innodb_ft_parser = 'ngram';,并重建索引,否则MATCH(col) AGAINST('数据库')会拆成“数据”“库”,而非“数据库”整词
迁移后必须重设 innodb_ft_* 配置项,否则默认值无效
MySQL 5.7 默认未启用 ngram,也未加载中文停用词,ALTER TABLE ... ENGINE=InnoDB 不会继承 MyISAM 的全文配置,全是空白起点。
- 确认已开 ngram:
SELECT @@innodb_ft_parser;应返回ngram,不是空或NULL - 重建索引前必须先改配置:
SET GLOBAL innodb_ft_min_token_size = 2;(按业务词长调),然后ALTER TABLE t DROP INDEX ft_idx; ALTER TABLE t ADD FULLTEXT(ft_col); - 重启后需运行
OPTIMIZE TABLE t才能触发全文索引同步,否则INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE为空
最易被忽略的一点:InnoDB 全文索引对 CHAR 和 VARCHAR 字段的行为一致,但对 TEXT 类型字段,默认最大索引长度是 1000 字符,超长部分不参与分词——MyISAM 没这限制。线上表若含长文本摘要,必须加 WITH PARSER ngram 并确认实际分词截断点。


















