myisam不支持中文分词,仅按空格标点切分;建全文索引必须显式添加,否则match()报错1191;against()需配对指定模式,布尔模式漏写in boolean mode则操作符失效;中文检索必须用ngram(仅innodb支持)或外接es/sphinx。

MyISAM 本身不支持真正的“分词”,尤其对中文——它只按空格、标点切分,没内置中文分词能力。指望 MyISAM 做中文全文检索,基本等于手动写个 LIKE '%关键词%' 还慢。
下面直说关键动作和踩坑点:
建全文索引前必须显式定义,否则 MATCH() 直接报错 1191
没索引就写 MATCH(title) AGAINST('xxx'),MySQL 不会帮你建,而是甩出:Error 1191: Can't find FULLTEXT index matching the column list。
- 建表时加:
CREATE TABLE t (id INT, content TEXT, FULLTEXT(content)) ENGINE=MyISAM; - 已有表加:
ALTER TABLE t ADD FULLTEXT(content);(注意:MyISAM 加索引全程锁表,大数据量别在高峰期跑) - 验证是否生效:
SHOW INDEX FROM t WHERE Key_name LIKE 'ft%';
AGAINST() 必须配对使用模式,布尔模式漏 IN BOOLEAN MODE 就失效
写成 AGAINST('+mysql -tutorial') 是无效的——+ 和 - 在自然语言模式下就是普通字符;只有加上 IN BOOLEAN MODE 才被识别为操作符。
- 自然语言模式(默认):
MATCH(c) AGAINST('数据库优化' IN NATURAL LANGUAGE MODE),返回相关性分数,可ORDER BY排序 - 布尔模式(推荐控制逻辑):
MATCH(c) AGAINST('+数据库 +优化' IN BOOLEAN MODE),返回 0/1,不能排序,但支持+、-、>、 - 别混用:
AGAINST('+mysql' IN NATURAL LANGUAGE MODE)不报错但 + 没意义
中文根本没法靠 MyISAM 原生分词,调 ft_min_word_len 或换字符集只是掩耳盗铃
存 “数据库优化是关键”,MyISAM 默认当一个词处理;设 ft_min_word_len = 2 后,它也不会拆成“数据”“库优”“优化”,而是截断首尾或生成大量无意义双字组合。
- 改配置需重启 MySQL,且影响全局所有 MyISAM 表
- gbk/gb2312 + 自定义停用词表仍无法解决连续汉字切分问题
- 人工加空格(如存成“数据 库 优 化”)破坏语义,查“数据库”就匹配不到
- 真正能用的方案只有两个:
ngram(仅 InnoDB 支持)、或外挂Elasticsearch/Sphinx
50% 阈值和停用词导致静默失败,查不到结果可能根本没报错
如果搜索词在超过半数行中都出现(比如全表 100 行,“的”出现在 51 行),MyISAM 直接过滤掉这个词,查询返回空——连 warning 都不给。
- 停用词列表不可动态修改,只能改配置文件后重启
-
INFORMATION_SCHEMA.STATISTICS查不到停用词命中情况,得靠SELECT COUNT(*) FROM t WHERE content LIKE '%词%'反向验证是否被阈值干掉 - 小数据集(
MyISAM 全文索引的适用场景其实很窄:英文为主、词长稳定、无复杂逻辑、能接受静默过滤。一旦涉及中文、模糊匹配、高精度召回,它不是“不够好”,而是“根本不能用”。











