全文索引不是LIKE的升级版,而是面向自然语言语义匹配的独立查询范式;需手动启用、建目录、唯一索引及全文索引,查询须用CONTAINS或CONTAINSTABLE,不支持通配符和实时更新。

全文索引不是 LIKE 的“升级版”,而是完全不同的查询范式——它不解决 LIKE '%关键词%',但能高效替代自然语言场景下的模糊意图。
SQL Server 的 FULLTEXT 索引必须显式启用且重建
默认安装的 SQL Server 不会自动开启全文搜索功能,即使你执行了 CREATE FULLTEXT INDEX,也会报错 The full-text search feature is not enabled。必须先运行:
EXEC sp_fulltext_database 'enable'
然后为表创建目录、唯一索引、再建全文索引:
CREATE FULLTEXT CATALOG ft_catalog AS DEFAULT; CREATE UNIQUE INDEX ui_Users_ID ON Users(UserID); -- 全文索引强制要求唯一键 CREATE FULLTEXT INDEX ON Users(UserName, Email) KEY INDEX ui_Users_ID;
注意:KEY INDEX 必须是唯一、非空、单列的索引;UserName 和 Email 字段类型需为 char/varchar/nvarchar 等文本类型,不能是 text(已弃用)或 xml(需额外配置)。
查询语法从 LIKE 彻底切换到 MATCH ... AGAINST
不能混用,也不能把 FULLTEXT 当作普通索引加速 LIKE。正确写法只有两种:
-
SELECT * FROM Users WHERE CONTAINS((UserName, Email), 'zhang')—— 支持布尔操作(AND/OR/NOT),但不返回相关性排序 -
SELECT *, RANK() OVER (ORDER BY KEY_TBL.RANK DESC) AS Score FROM Users INNER JOIN CONTAINSTABLE(Users, (UserName, Email), 'zhang') AS KEY_TBL ON Users.UserID = KEY_TBL.[KEY]—— 返回匹配度RANK,适合排序展示
常见错误包括:CONTAINS(UserName, '%zhang%')(通配符无效)、CONTAINS(UserName, N'张')(中文需确认全文目录的语言设置是否为简体中文,否则分词失败)、在没有 CONTAINSTABLE 的情况下直接用 RANK()(会报错 Invalid column name 'RANK')。
全文索引对数据变更延迟敏感,CHANGE_TRACKING 模式要选对
全文索引不是实时更新的,默认使用 MANUAL 或 INCREMENTAL 模式,新插入/更新的数据不会立刻可搜。常见配置:
-
CHANGE_TRACKING AUTO:依赖事务日志,延迟通常在秒级,但增加日志压力 -
CHANGE_TRACKING MANUAL:必须手动执行ALTER FULLTEXT INDEX ... START UPDATE POPULATION才能同步,适合低频更新场景 -
POPULATION过程本身可能锁表或显著拖慢大表,1 亿行表首次填充可能耗时数小时
验证是否生效:查系统视图 sys.fulltext_index_columns 确认字段已加入;执行 SELECT * FROM sys.dm_fts_index_keywords(DB_ID(), OBJECT_ID('Users')) 看是否有分词输出;避免只靠“没报错”就认为已就绪。
全文索引不解决所有模糊需求,%关键词% 类场景仍需其他方案
全文索引擅长的是语义匹配(如“java developer”匹配“Java 开发工程师”),但对以下情况无能为力:
- 纯字符位置匹配(如“第 5 位是 x,第 8 位是 y”)
- 拼音/形近字纠错(如搜“zhangsan”想命中“张三”)
- 超短关键词(单字、二字词默认被停用词表过滤,需自定义停用词)
- 大小写/全半角敏感控制(需在全文目录属性中关闭
Accent Sensitive或调整语言)
如果业务强依赖 LIKE '%keyword%',全文索引不是银弹——这时候该考虑 Elasticsearch 倒排+前缀补全,或者把高频模糊字段抽出来做独立倒排表,而不是硬塞进 SQL Server 全文引擎里。


















