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 实现"相关度排序"

相关推荐
小江的记录本3 分钟前
【MyBatis-Plus】Spring Boot + MyBatis-Plus 进行各种数据库操作(附完整 CRUD 项目代码示例)
java·前端·数据库·spring boot·后端·sql·mybatis
落叶花开又一年5 分钟前
检验检测机构资质认定远程评审工作程序
linux·运维·服务器
wanhengidc6 分钟前
《三国志异闻录》搬砖新游戏 云手机
运维·服务器·数据库·游戏·智能手机
2301_8073671911 分钟前
Python日志记录(Logging)最佳实践
jvm·数据库·python
2301_7957417923 分钟前
构建一个基于命令行的待办事项应用
jvm·数据库·python
i建模27 分钟前
通过命令行使用密钥登录远程SSH主机
运维·ssh
FITA阿泽要努力37 分钟前
《实战SQL: GROUP BY》
数据库·sql
sw1213891 小时前
Python字典与集合:高效数据管理的艺术
jvm·数据库·python
旺仔.2911 小时前
僵死进程及Linux文件操作 详解
linux·运维·服务器
ShiJiuD6668889991 小时前
mysql 基础笔记一
数据库·笔记·mysql