MyISAM全文索引语法更宽松,支持CHAR/VARCHAR/TEXT多列组合且无需解析器;InnoDB仅支持VARCHAR/TEXT、需显式IN BOOLEAN MODE才识别±操作符、MATCH字段顺序与索引定义必须严格一致、中文需ngram插件及utf8mb4字符集。

MyISAM全文索引创建语法更宽松,但字段类型限制少
MyISAM允许在CHAR、VARCHAR、TEXT列上直接建FULLTEXT索引,甚至支持多列组合且无需显式指定解析器。例如:
CREATE TABLE articles ( id INT PRIMARY KEY, title CHAR(100), body TEXT, FULLTEXT(title, body) ) ENGINE=MyISAM;
而InnoDB从5.6起才支持全文索引,且严格限定仅VARCHAR和TEXT列可用——若定义为CHAR(200),即使写了FULLTEXT(col),InnoDB也会静默忽略,SHOW INDEX里根本看不到该索引。
InnoDB必须显式声明IN BOOLEAN MODE才能用+/-操作符
MyISAM默认自然语言模式下AGAINST('mysql tutorial')会做词频加权匹配,也兼容布尔语法(部分版本),但InnoDB在自然语言模式下会过滤停用词、强制最小词长,且完全不识别+、-、>等操作符——漏写IN BOOLEAN MODE就等于白写:
-
MATCH(title) AGAINST('+MySQL -tutorial' IN BOOLEAN MODE)✅ 有效 -
MATCH(title) AGAINST('+MySQL -tutorial')❌ 返回空或全表扫描(EXPLAIN显示type=ALL)
另外,InnoDB的布尔模式不支持左模糊(*mysql)或中模糊(my*sql),只认词尾通配:mysql*。
MATCH()字段顺序与名称必须和索引定义一字不差
MyISAM对MATCH()里的字段顺序较宽容,比如索引是FULLTEXT(body, title),查MATCH(title, body)有时也能走索引(取决于版本)。InnoDB则完全严格:
- 索引定义为
FULLTEXT(content),但查询写成MATCH(`content `)(末尾带空格)→ 失效 - 索引是
FULLTEXT(title, content),却只写MATCH(title)→ 字段数不匹配,EXPLAIN显示key=NULL - 哪怕列名大小写不一致(如建表用
CONTENT,查询用content),在严格SQL模式下也可能失败
字符集与分词配置差异导致同样SQL结果不同
MyISAM用空格/标点切词,对字符集要求低;InnoDB依赖ngram或mechanical解析器,且仅utf8mb4(非utf8别名)或latin1等支持分词。常见坑:
-
SELECT @@innodb_ft_min_token_size返回3→ 搜'go'或'a'永远无结果,MyISAM默认是4但可调低 -
SELECT @@innodb_ft_server_stopword_table指向内置停用词表 →'the'、'and'被静默跳过,MyISAM默认停用词更少 - 建表时没加
WITH PARSER ngram且用utf8mb4,中文字段实际无法被InnoDB分词,查不到任何内容
最易被忽略的是:InnoDB全文索引不是“开了就能搜”,而是每个环节(引擎、列类型、字符集、词长、停用词、语法)都得对齐,缺一不可。


















