SQL Server 之 Full-Text Search 全文搜索

SQL Server 的 全文搜索(Full-Text Search) 是一种高性能、支持自然语言查询的文本检索功能,特别适用于对 大文本字段(如 VARCHAR(MAX)、NVARCHAR、TEXT 等)进行关键词搜索,相比 LIKE '%关键词%' 有显著优势。

一、为什么需要 Full-Text Search?

典型场景:电商商品名称/描述搜索

新闻文章内容检索

用户评论关键词分析

二、启用 Full-Text Search(前提)

(默认安装通常已包含)

  • SQL Server 安装时需勾选 "Full-Text and Semantic Extractions for Search"
  • 数据库必须启用全文搜索:
sql 复制代码
-- 检查是否启用
SELECT DATABASEPROPERTYEX('YourDB', 'IsFullTextEnabled');
-- 返回 1 表示已启用

-- 若未启用,执行:
EXEC sp_fulltext_database 'enable';

三、创建全文索引(Full-Text Index)

步骤 1:确保表有唯一非空索引(通常是主键)

sql 复制代码
CREATE TABLE Articles (
    Id INT IDENTITY PRIMARY KEY,        -- 必须有唯一索引
    Title NVARCHAR(200),
    Content NVARCHAR(MAX),
    CreatedDate DATETIME
);

步骤 2:创建全文目录(Catalog)

sql 复制代码
-- 创建全文目录(逻辑容器)
CREATE FULLTEXT CATALOG ft_catalog AS DEFAULT;

步骤 3:在目标列上创建全文索引

sql 复制代码
-- 对 Title 和 Content 列创建全文索引
CREATE FULLTEXT INDEX ON Articles (
    Title LANGUAGE 1033,          -- 1033 = English, 2052 = 简体中文
    Content LANGUAGE 2052         -- 中文分词需指定 LANGUAGE 2052
)
KEY INDEX PK__Articles__Id      -- 指定唯一键索引名(通常是主键)
ON ft_catalog                   -- 指定目录
WITH CHANGE_TRACKING AUTO;      -- 自动跟踪数据变更

中文支持关键:必须指定 LANGUAGE 2052(简体中文)或 LANGUAGE N'Chinese (Simplified)'

SQL Server 2017+ 内置中文分词器(无需额外安装)

四、使用全文搜索查询

  1. CONTAINS ------ 精确关键词/短语搜索
sql 复制代码
-- 搜索 Title 或 Content 中包含 "数据库" 的文章
SELECT * FROM Articles
WHERE CONTAINS((Title, Content), N'数据库');

-- 搜索短语(带引号)
SELECT * FROM Articles
WHERE CONTAINS(Content, '"高性能数据库"');

-- 多关键词(AND / OR)
SELECT * FROM Articles
WHERE CONTAINS(Title, N'"SQL" AND "优化"');

-- 前缀匹配(* 通配符)
SELECT * FROM Articles
WHERE CONTAINS(Title, N'"数据*"');  -- 匹配 "数据库", "数据中心" 等
  1. FREETEXT ------ 自然语言搜索(自动分词、同义词)
sql 复制代码
-- 自动匹配相关词(如搜 "汽车" 可能返回 "轿车"、"车辆")
SELECT * FROM Articles
WHERE FREETEXT((Title, Content), N'新能源汽车技术');
  1. CONTAINSTABLE / FREETEXTTABLE ------ 返回相关性排名
sql 复制代码
-- 获取匹配结果并按相关性排序(Rank 越高越相关)
SELECT a.*, ft.Rank
FROM Articles a
INNER JOIN CONTAINSTABLE(Articles, (Title, Content), N'数据库') ft
    ON a.Id = ft.[KEY]
ORDER BY ft.Rank DESC;

五、中文分词注意事项

  1. 验证中文分词是否生效
sql 复制代码
-- 查看 "数据库优化" 如何被分词
SELECT display_term, occurrence_count
FROM sys.dm_fts_parser(N'"数据库优化"', 2052, 0, 0);
-- 预期输出:数据库、优化(两个词)
  1. 常见问题

→ 检查是否指定了 LANGUAGE 2052

→ 检查全文索引是否已填充(见下文)

  • 搜索不到结果?
  • 单字无法搜索?

→ SQL Server 中文分词默认不索引单字(如搜 "数" 可能无效),建议用双字以上词

六、管理全文索引

手动启动索引填充(首次创建后需执行)

sql 复制代码
-- 完全填充
ALTER FULLTEXT INDEX ON Articles START FULL POPULATION;

-- 增量填充(基于时间戳列)
ALTER FULLTEXT INDEX ON Articles START INCREMENTAL POPULATION;

查看索引状态

sql 复制代码
-- 查询填充进度
SELECT 
    OBJECT_NAME(object_id) AS TableName,
    status_description
FROM sys.dm_fts_index_population;

删除全文索引

sql 复制代码
DROP FULLTEXT INDEX ON Articles;
DROP FULLTEXT CATALOG ft_catalog;

七、性能与最佳实践

常见误区

1 以为全文索引是"普通索引的增强版"

→ 它是独立的倒排索引结构,和 B-Tree 索引完全不同。

2 在 WHERE 中混用 LIKE 和 CONTAINS

→ 应优先用 CONTAINS,避免 LIKE 拖慢性能。

3 未处理停用词(Stopwords)

→ 如 "的"、"是" 等高频词默认被忽略,可通过自定义停用词表调整。

示例:电商商品搜索

sql 复制代码
-- 商品表
CREATE TABLE Products (
    Id INT PRIMARY KEY,
    Name NVARCHAR(200),
    Description NVARCHAR(MAX)
);

-- 创建全文索引(中文)
CREATE FULLTEXT INDEX ON Products (Name, Description LANGUAGE 2052)
KEY INDEX PK__Products__Id
ON ft_catalog;

-- 搜索 "华为手机"
SELECT Id, Name, Description
FROM Products
WHERE CONTAINS((Name, Description), N'华为 AND 手机')
ORDER BY Id;

当你的应用需要对大文本字段做高效、智能的关键词搜索时,Full-Text Search 是 SQL Server 的最佳选择。中文场景:务必指定 LANGUAGE 2052

性能关键:用 CONTAINS 替代 LIKE '%...%'

用户体验:用 CONTAINSTABLE 实现"相关度排序"

相关推荐
m0_550024632 分钟前
持续集成/持续部署(CI/CD) for Python
jvm·数据库·python
AC赳赳老秦3 分钟前
代码生成超越 GPT-4:DeepSeek-V4 编程任务实战与 2026 开发者效率提升指南
数据库·数据仓库·人工智能·科技·rabbitmq·memcache·deepseek
人鱼传说11 分钟前
docker desktop是一个好东西
运维·docker·容器
啦啦啦_999916 分钟前
Redis-2-queryFormat()方法
数据库·redis·缓存
Thera77740 分钟前
【Linux C++】彻底解决僵尸进程:waitpid(WNOHANG) 与 SA_NOCLDWAIT
linux·服务器·c++
阿梦Anmory1 小时前
Ubuntu配置代理最详细教程
linux·运维·ubuntu
呉師傅1 小时前
【使用技巧】Adobe Photoshop 2024调整缩放与布局125%后出现点菜单项漂移问题的简单处理
运维·服务器·windows·adobe·电脑·photoshop
heartbeat..1 小时前
JVM 性能调优流程实战:从开发规范到生产应急排查
java·运维·jvm·性能优化·设计规范
玄同7651 小时前
SQLite + LLM:大模型应用落地的轻量级数据存储方案
jvm·数据库·人工智能·python·语言模型·sqlite·知识图谱
吾日三省吾码1 小时前
别只会“加索引”了!这 3 个 PostgreSQL 反常识优化,能把性能和成本一起打下来
数据库·postgresql