sql性能优化:sql Server 怎么添加全文索引+语法深度剖析+测试

如果对“简述”、“概述” 不感谢请求可以直接跳到“三、添加全文索引”

一、简述

在SQL Server 中提供了一种名为全文索引的技术,可以大大提高从长字符串里搜索数

据的速度,不用在用LIKE这样低效率的模糊查询了。

二、全文索引概念

官方:https://docs.microsoft.com/zh-cn/sql/relational-databases/search/full-text-search?view=sql-server-ver15

 

1.全文索引是针对数据表,只能对表创建全文索引,不能对数据库创建全文索引。

2.每个数据库可以不包含全文目录或包含多个全文目录,一个全文目录可以包含多个全文索引,但一个全文索引只能用于构成一个全文目录。

3.一个数据表只能创建一个全文索引,一个全文索引可以包含多个字段。

4.创建全文索引的表必须要有一个唯一的非空索引,并且这个唯一的非空的索引只能是一个字段,不能是组合字段。

5.每个表只允许有一个全文索引。若要对某个表创建全文索引,该表必须具有一个唯一且非 Null 的列。您可以对以下类型的列创建全文索引:char、varchar、nchar、nvarchar、text、ntext、image、xml、varbinary 和 varbinary(max),从而可对这些列进行全文搜索。对数据类型为 varbinary、varbinary(max)、image 或 xml 的列创建全文索引需要您指定类型列。类型列是用来存储每行中文档的文件扩展名(.doc、.pdf、xls 等)的表列。

全文搜索由全文引擎提供支持。全文引擎有两个角色:索引支持和查询支持。

全文索引包括表中一个或多个基于字符的列。 这些列可以具有以下任何数据类型:charvarcharncharnvarchartextntextimagexml 或 varbinary(max) 和 FILESTREAM。 每个全文索引都对表中的一个或多个列创建索引,并且每个列都可以使用特定语言。

全文查询根据特定语言(例如,英语或日语)的规则对词和短语进行操作,从而依据全文索引中的文本数据执行语言搜索。 全文查询可以包括简单的词和短语,或者词或短语的多种形式。 全文查询返回包含至少一个匹配项(也称为“命中”)的所有文档。 当目标文档包含在全文查询中指定的所有字词,并符合任何其他搜索条件(如匹配的字词之间的距离)时,即发生匹配。

全文搜索体系结构

全文搜索体系结构包括以下进程:

  • SQL Server 进程 (sqlservr.exe)。

  • 筛选器后台程序宿主进程 (fdhost.exe)。

    为了安全起见,筛选器由称为筛选器后台程序宿主的单独进程加载。 fdhost.exe 进程是由 FDHOST 启动器服务 (MSSQLFDLauncher) 创建的,这些进程使用 FDHOST 启动器服务帐户的安全凭据运行。 因此,必须运行 FDHOST 启动器服务才能正常进行全文索引和全文查询。 有关设置此服务的服务帐户的信息,请参阅 设置用于全文筛选器后台程序启动器的服务帐户

这两个进程包含全文搜索体系结构的各组件。 下图概括了这些组件及其关系。  

全文搜索查询与 LIKE 谓词的对比

与全文搜索不同,LIKE Transact-SQL 谓词仅对字符模式有效。 另外,不能使用 LIKE 谓词来查询格式化的二进制数据。 此外,对大量非结构化的文本数据执行 LIKE 查询要比对相同数据执行同样的全文查询慢得多。 对数百万行文本数据进行的 LIKE 查询可能需要几分钟的时间才能返回结果;而对于同样的数据,全文查询只需要几秒甚至更少的时间,具体取决于返回的行数。

每个表只允许有一个全文索引

若要对某个表创建全文索引,该表必须具有一个唯一且非 Null 的列。 你可以在 char、 varchar、 nchar、 nvarchar、 text、 ntext、 image、 xml、 varbinary 类型的列上生成全文索引,并且可对 varbinary(max) 索引以进行全文搜索。 在数据类型为 varbinary、 varbinary(max) 、 image 或 xml 的列上创建全文索引需要你指定类型列。 类型列 是用来存储每行中文档的文件扩展名(.doc、.pdf、xls 等)的表列。

三、添加全文索引

下面简明的介绍如何使用Sql2008 全文索引

3.1检查服务里面带有Full-text字样的服务是否存在并开启

 如果不存在带有Full-text字样的服务的,确认是否安装了sqlserverFullTextSearch

--检查数据库PS2是否支持全文索引,如果不支持
--则使用sp_fulltext_database 打开该功能 

if(select databaseproperty('PS2','isfulltextenabled'))=0
execute sp_fulltext_database 'enable'

3.2新建全文目录

 

全文目录是用来存储全文索引的

3.3为表定义全文索引

 3.4点击下一步,按提示选择

3.4.1确认下一步

用语句创建全文目录  

CREATE FULLTEXT CATALOG [FD_HouseSearch]WITH ACCENT_SENSITIVITY = ON
AS DEFAULT
AUTHORIZATION [dbo]

 3.4.2选择唯一索引,通常是主键

 3.4.3选择要建立的全文索引列,对于断字符的选择如果列存的是中文就选择chinese,如果是英文就选择English

选择需要全文搜索的列,并且选择断字符语言,因为该字段主要用来存储中文,所以这里也选择了简体中文。

断字符:断字符用来对全文搜索数据进行语言分析,查找单词的边界,也就是怎样将一段很长的内容拆分成日常的词语或字。例如“全文搜索”,可能会断字成“全文”、‘搜索’、‘全’、‘文’、‘搜’、‘索’等符合中国人正常的习惯的词或字。 

后期可以通过《表》鼠标右键>全文索引>属性>会弹出新的窗口>选择“列表”>修改“断字符语言”

 

3.4.4 选择索引更新方式,可以先自动更新,以后数据量大了可以设置添加全文索引的计划

 

 3.4.5 选择全文目录

选择全文目录、索引文件、非索引字表

非索引字表:在刚才的断字中讲了怎样断字,这里就是将断的字保存在一张表中,该处选择系统默认的非索引字表.

----查询断字表
SELECT TOP 1000 * FROM sys.dm_fts_index_keywords(db_id(''), object_id(''))

 用语句创建全文索引

--语句少了很多默认参数,其它就按系统默认即可
CREATE FULLTEXT INDEX ON dbo.Housetest
(Description
)
KEY INDEX PK_Housetest
ON FD_HouseSearch

 四、全文索引的SQL查询关键字

建立好全文索引后就可以使用SQL语句来查询了,主要用带三个关键字 CONTAINS、FREETEXT、CONTAINSTABLE和FREETEXTTABLE

4.1 CONTAINS

搜索单个词和短语的精确或模糊的匹配项,要搜索的内容必须是个有意义的词语,比如说“苹果”、“建设厅”,不能是一些没意义的词语,比如“阿迪撒啊是”,“儿儿的”这样的词语即使

LIKE是能查询出来,但全文索引对这样没意义的词语可能没有建立索引,查不出来

详细查看:CONTAINS (Transact-SQL) - SQL Server | Microsoft Docs

SELECT *   
FROM dbo.Business  
WHERE CONTAINS(Address,'旅游')  

 实现功能:查询Business表中Address列包含“旅游”的行

 4.2 FREETEXT

 和CONTAINS类似,不同的是它会先把要查询的词语先进性分词然后在查询匹配项

 详细查看:FREETEXT (Transact-SQL) - SQL Server | Microsoft Docs

select *    
from dbo.Business     
where freetext(Address,'带婴儿旅游') 

 

4.3 CONTAINS  和 FREETEXT 的区别

SELECT id, name FROM Teacher
WHERE CONTAINS(note, 'heard')
 
SELECT id, name FROM Teacher
WHERE FREETEXT(note, 'heard')

 这两个结果集 的区别 第一个 出来 0 条 第二个出来2条

原因是  FREETEXT 相较于 CONTAINS 比较松散 可以 查出 'hearder' 

咋一看来 感觉FREETEXT 比 CONTAINS  比起来 更灵活好用 其实不然 

 4.4 CONTAINS  的高级用法

  • 对多列进行匹配
  • 与或非逻辑
  • 模糊匹配 支持 英文单词的变形
  • 通配符
  • 查询权重

以下的例子 都是从 sqlserver 官方文档 获取的

--多列查询
SELECT Name, ListPrice  
FROM Production.Product  
WHERE ListPrice = 80.99  
   AND CONTAINS((Name,title), 'Mountain');  
--column_list指定以逗号分隔的两个或更多个列。 column_list 必须用括号括起来。 除非指定 
--language_term,否则 column_list 中所有列的语言必须相同。
--------------------------------------------------------------------------------------
-- 与或非 逻辑
SELECT Name, ListPrice  
FROM Production.Product  
WHERE ListPrice = 80.99  
   AND CONTAINS(Name, '"Mountain" AND "WENJIE"'); 
--<AND> ::={ AND | & }  
--<AND NOT> ::={ AND NOT | &! }  
--<OR> ::=   { OR | | } 
--------------------------------------------------------------------------------------
-- 模糊匹配 支持 英文单词变形 类似于 FREETEXT
-- 可以读出ride 的各种形式(如 riding 和 ridden 等)
 SELECT Description  
FROM Production.ProductDescription  
WHERE CONTAINS(Description, ' FORMSOF (INFLECTIONAL, ride) ')
 
--------------------------------------------------------------------------------------
-- 通配符*的使用
SELECT Name  
FROM Production.Product  
WHERE CONTAINS(Name, ' "Chain*" ');  
--------------------------------------------------------------------------------------
--查询权重
SELECT Description  
FROM Production.ProductDescription  
WHERE CONTAINS(Description, 'ISABOUT (performance weight (.8),   
comfortable weight (.4), smooth weight (.2) )' );  
---------------------------------------------------------------------------------------
-- NEAR 使用 
-- 以下示例在 Production.ProductReview 表中搜索包含 bike 一词、在“control”词的 10 个词范围内且使用指定顺序(即,“bike”排在“control”前面)的所有注释。
SELECT Comments  
FROM Production.ProductReview  
WHERE CONTAINS(Comments , 'NEAR((bike,control), 10, TRUE)');  

注意以上的 所以 可以 混合使用 

比如我这里的sql

SELECT * FROM sku_price WHERE 
CONTAINS(sku_desc, 'ISABOUT("PJ" weight (.8) ,"PJ*" weight (.2)) AND ISABOUT("PA" weight (.8) ,"PA*" weight (.2))')
 
--查询 sku_price 中 匹配 PJ 或者 PJ* 但是 PJ 的权重大于 PJ* 的结果集

4.5 CONTAINSTABLE

在查询方式上与 CONTAINS 几乎一样。但CONTAINSTABLE 返回的是符合查询条件的表,在 SQL 语句中我们可以把它当作一个普通的表来使用,并且使用 CONTAINSTABLE 的查询对每一行返回一个相关性排名值 (RANK) 和全文键 (KEY)。 

 详细查看:CONTAINSTABLE (SQL) - SQL Server | Microsoft Docs

SELECT  *  
FROM    Business AS FT_TBL  
        INNER JOIN CONTAINSTABLE(Business, *, 'ISABOUT (婴儿 WEIGHT (.8),赤水 WEIGHT (.4) )')  
        AS KEY_TBL ON FT_TBL.BusinessId = KEY_TBL.[KEY]  
ORDER BY KEY_TBL.RANK DESC  

ISABOUT 是这种查询的关键字,weight 指定了一个介于 0~1之间的数,类似系数。表示不同条件有不同的侧重。

CONTAINSTABLE 返回的表包含有特殊的两列:KEY,RANK。

被全文索引的表必须有唯一索引。这个唯一的索引列在返回的表中就成为 KEY。我们通常把它作为表连接的条件。

在某些网站搜索时,结果中会出现表示匹配程度的数字,RANK 与此类似。它的值在0~1000之间,标识每一行与查询条件的匹配程度,程度越高,RANK 的值大,通常情况下,按照 RANK 的降序排列。

4.6 FREETEXTTABLE

在查询方式上与 FREETEXT 几乎一样。但 FREETEXTTABLE 返回的是符合查询条件的表,在 SQL 语句中我们可以把它当作一个普通的表来使用,并且使用  FREETEXT  的查询对每一行返回一个相关性排名值 (RANK) 和全文键 (KEY)。

详细查看:FREETEXTTABLE (SQL) - SQL Server | Microsoft Docs

SELECT  * ,  
        BusinessID ,  
        Address  
FROM    Business AS FT_TBL  
        INNER JOIN FREETEXTTABLE(Business, Address, 'ISABOUT (带婴儿旅游 WEIGHT (.8),赤水 WEIGHT (.4) )')  
        AS KEY_TBL ON FT_TBL.BusinessId = KEY_TBL.[KEY]  
ORDER BY KEY_TBL.RANK DESC 

 

 

五、全文索引相关命令

--activate,是激活表的全文检索能力,也就是在全文目录中注册该表

execute sp_fulltext_table 'ProSearch','activate'

--填充全文索引目录

execute sp_fulltext_catalog 'ProSearchCatalog','start_full'

--查询全文索引是否建立完毕(0:完毕;1:正在建立)

select fulltextcatalogproperty('ProSearchCatalog','populateStatus')

查看全文检索的配置情况:

sp_help_fulltext_catalogs -- 检查数据库有哪些全文目录
sp_help_fulltext_tables ProSearchCatalog -- 查看哪些表把全文索引建立在T_testData下
sp_help_fulltext_columns ProSearch -- 查看test表哪些字段配置了全文索引

删除全文索引必须与创建的时候倒过来一步一步操作:

drop fulltext index on test -- 撤销test上的全文检索
drop fulltext catalog FT_testData -- 撤销全文目录FT_testData

5.1 创建测试表

DROP TABLE FullTextIndexing

CREATE TABLE FullTextIndexing
(
	ID INT IDENTITY(1,1) NOT NULL,
	Sentence VARCHAR(MAX)
)

5.2 创建聚集索引

ALTER TABLE FullTextIndexing ADD CONSTRAINT PK_FullTextIndexing PRIMARY KEY CLUSTERED(ID ASC)
GO

--	将"全文搜索概述"页面的文字全部拷贝到txt,然后倒入到表FullTextIndexing中
--	https://msdn.microsoft.com/zh-cn/library/ms142547(v=sql.105).aspx

重复15次,从47行变为154万行

INSERT INTO FullTextIndexing(Sentence)
SELECT Sentence FROM FullTextIndexing
GO 15
 
 
SELECT COUNT(*) FROM FullTextIndexing

5.3 创建全文目录

官方:CREATE FULLTEXT CATALOG (Transact-SQL) | Microsoft Docs

CREATE FULLTEXT CATALOG [Catalog_Test]
WITH
	ACCENT_SENSITIVITY = ON	--区分重音
	AS DEFAULT				--默认目录
	AUTHORIZATION [dbo];--全文目录的所有者
GO

5.4 更改全文目录的属性

官方:ALTER FULLTEXT CATALOG (Transact-SQL) | Microsoft Docs

ALTER FULLTEXT CATALOG [Catalog_Test] 
REBUILD WITH ACCENT_SENSITIVITY = ON;	--重新生成整个目录并区分重音
--REORGANIZE;	--重新组织全文目录
--AS DEFAULT;	--指定此目录为默认目录
GO

5.5 从数据库中删除全文目录(先删除全文索引)

官方:DROP FULLTEXT CATALOG (Transact-SQL) | Microsoft Docs

DROP FULLTEXT CATALOG [Catalog_Test];
GO

5.6 创建干扰字表

官方:CREATE FULLTEXT STOPLIST (Transact-SQL) | Microsoft Docs

CREATE FULLTEXT STOPLIST [Stoplist_Test] 
FROM SYSTEM STOPLIST 
AUTHORIZATION [dbo];
GO  

5.7 添加删除干扰字

官方:ALTER FULLTEXT STOPLIST (Transact-SQL) | Microsoft Docs

ALTER FULLTEXT STOPLIST [Stoplist_Test]
ADD N'乎' LANGUAGE 2052;
GO 
 
ALTER FULLTEXT STOPLIST [Stoplist_Test]
DROP N'乎' language 2052;   
--ALL LANGUAGE 'English' 
--ALL
GO 

5.8 从数据库中删除全文本非索引字表

官方:DROP FULLTEXT STOPLIST (Transact-SQL) | Microsoft Docs

DROP FULLTEXT STOPLIST [Stoplist_Test];
GO 

5.9 创建全文索引

官方:CREATE FULLTEXT INDEX (Transact-SQL) | Microsoft Docs

CREATE FULLTEXT INDEX ON [dbo].[FullTextIndexing]
(Sentence LANGUAGE 2052)		--索引列,明确列中存储的语言,方便过滤
KEY INDEX PK_FullTextIndexing	--全文键:当前表中唯一索引名称
ON [Catalog_Test]				--指定全文目录
WITH (
	STOPLIST [Stoplist_Test],	--指定全文非索引字表
	CHANGE_TRACKING AUTO		--自动填充
	);
GO

5.10 更改全文索引的属性

官方:ALTER FULLTEXT INDEX (Transact-SQL) | Microsoft Docs

5.11 激活全文索引

ALTER FULLTEXT INDEX ON [dbo].[FullTextIndexing] ENABLE;
GO

5.12 删除全文索引

官方:DROP FULLTEXT INDEX (Transact-SQL) | Microsoft Docs

DROP FULLTEXT INDEX ON [dbo].[FullTextIndexing];
GO

5.13 测试

5.13 节点的所有代码,是运行在一个sql文本里

常规查询方法(先查询全部数据,放到内存:154万行31秒)

SELECT * FROM FullTextIndexing
 

 

SET STATISTICS IO ON --开启磁盘活动量的相关信息
SET STATISTICS TIME ON --开启分析、编译和执行各语句所需的毫秒数

--SET STATISTICS IO (Transact-SQL) 是 导致 SQL Server 显示 Transact-SQL 语句所生成的磁盘活动量的相关信息。
--官方:https://docs.microsoft.com/zh-cn/sql/t-sql/statements/set-statistics-io-transact-sql?view=sql-server-ver15
 
--关闭使用:
--SET STATISTICS IO OFF

--SET STATISTICS TIME (Transact-SQL) 显示分析、编译和执行各语句所需的毫秒数。
--官方:https://docs.microsoft.com/zh-cn/sql/t-sql/statements/set-statistics-time-transact-sql?view=sql-server-ver15

--关闭使用:
--SET STATISTICS TIME OFF

SELECT * FROM FullTextIndexing WHERE Sentence LIKE '%全文索引%'

执行了几遍,耗时13440 毫秒
SQL Server 分析和编译时间: 
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
(229376 行受影响)
表 'FullTextIndexing'。扫描计数 1,逻辑读取 15633 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
SQL Server 执行时间:
CPU 时间 = 11591 毫秒,占用时间 = 13440 毫秒。 

SELECT * FROM FullTextIndexing WHERE CHARINDEX('全文索引',Sentence)<>0

执行了几遍,耗时15338 毫秒
SQL Server 分析和编译时间: 
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
(229376 行受影响)
表 'FullTextIndexing'。扫描计数 1,逻辑读取 15633 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
SQL Server 执行时间:
CPU 时间 = 12714 毫秒,占用时间 = 15338 毫秒。

 

--	使用全文索引的方法:
SELECT * FROM [dbo].[FullTextIndexing] WHERE FREETEXT(Sentence,'全文索引');

执行了几遍,耗时17402 毫秒
SQL Server 分析和编译时间: 
CPU 时间 = 16 毫秒,占用时间 = 21 毫秒。
(851968 行受影响)
表 'FullTextIndexing'。扫描计数 1,逻辑读取 15633 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
SQL Server 执行时间:
CPU 时间 = 2230 毫秒,占用时间 = 17402 毫秒。

 执行了17秒,不降反而上升了!!~

重新生成全文目录!~再执行

(更多方法有待参考:使用全文搜索查询 SQL Server)使用全文搜索查询 SQL Server | Microsoft Docs

ALTER FULLTEXT CATALOG [Catalog_Test] REBUILD;
GO
SELECT * FROM [dbo].[FullTextIndexing] WHERE FREETEXT(Sentence,'全文索引');
SELECT * FROM [dbo].[FullTextIndexing] WHERE CONTAINS(Sentence,'全文索引');
SELECT * FROM [dbo].[FullTextIndexing] WHERE CONTAINS(Sentence,'全文 AND 索引');


--SET STATISTICS IO (Transact-SQL) 是 导致 SQL Server 显示 Transact-SQL 语句所生成的磁盘活动量的相关信息。
--官方:https://docs.microsoft.com/zh-cn/sql/t-sql/statements/set-statistics-io-transact-sql?view=sql-server-ver15
 
SET STATISTICS IO OFF

--SET STATISTICS TIME (Transact-SQL) 显示分析、编译和执行各语句所需的毫秒数。
--官方:https://docs.microsoft.com/zh-cn/sql/t-sql/statements/set-statistics-time-transact-sql?view=sql-server-ver15

SET STATISTICS TIME OFF

这时快多了!~不到1秒就查询完成!~但是返回的行数才1000多行
SQL Server 分析和编译时间: 
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
(8853 行受影响)
表 'FullTextIndexing'。扫描计数 0,逻辑读取 27121 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
SQL Server 执行时间:
CPU 时间 = 78 毫秒,占用时间 = 944 毫秒。

不断地执行就会找出规律:
表扫描次数为0。
逻辑读也越来越多,耗时越来越多,查询返回的行数也越来越多,性能越来越差!~比"like"还差
最后还得重建重组(REBUILD/REORGANIZE)全文索引目录
 
逻辑读取 27121 次
逻辑读取 945268 次
逻辑读取 1212885 次
逻辑读取 1407846 次
逻辑读取 1736686 次
逻辑读取 1953265 次

5.14 查询句词拆分结果.可以看到按什么词语进行匹配查询

select * from sys.dm_fts_parser('全文索引',2052,5,0)
--	如果只需要全文键或排名的信息,可使用表值函数
--	使用表值函数的方法可以使用联接提示或查询提示(LOOP/MERGE/HASH)
ALTER FULLTEXT CATALOG [Catalog_Test] REBUILD;
GO
ALTER FULLTEXT CATALOG [Catalog_Test] REORGANIZE;
GO
 
SELECT * FROM [dbo].[FullTextIndexing] t1 
INNER JOIN CONTAINSTABLE([FullTextIndexing],Sentence,'概述') AS t2
ON t1.ID = t2.[KEY]
GO
 
SELECT * FROM [dbo].[FullTextIndexing] t1 
INNER JOIN FREETEXTTABLE([FullTextIndexing],Sentence,'概述',LANGUAGE 2052,1000) AS t2
ON t1.ID = t2.[KEY]
ORDER BY t2.RANK DESC;
GO

5.15 相关视图

select * from sys.syslanguages
select * from sys.fulltext_indexes
select * from sys.fulltext_catalogs where name = 'Catalog_Test'
select * from sys.dm_fts_active_catalogs where name = 'Catalog_Test'
select * from sys.fulltext_stoplists where name = 'Stoplist_Test'
select * from sys.fulltext_stopwords where stoplist_id = 5 --and language_id = 2052
select * from sys.dm_fts_parser('全文索引',2052,5,0)

六、概念和实例

6.1概念-全文谓词

全文查询使用全文谓词(CONTAINS 和 FREETEXT)以及全文函数(CONTAINSTABLE 和 FREETEXTTABLE)。它们支持复杂的 Transact-SQL 语法,这种语法支持各种形式的查询词。若要编写全文查询,必须了解何时以及如何使用这些谓词和函数。

CONTAINS 谓词可以搜索:

1.词或短语。
2.词或短语的前缀。
3.与另一个词相邻的词。
4.由另一个词的词形变化而生成的词(例如,drive 一词是 drives、drove、driving 和 driven 词形变化的词干)。
5.使用同义词库确定的另一个词的同义词(例如,metal 一词可能有 aluminum 和 steel 等同义词)。
 

---下面的示例将查找包含 
"Mountain"

USE AdventureWorks2008R2;
GO
SELECT Name, ListPrice
FROM Production.Product
WHERE CONTAINS(Name, 'Mountain');
GO
--下面的示例将查找包含 
"Mountain"或 "Road"
USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, ' "Mountain" OR "Road" ')
GO
---下面的示例返回的所有产品名称中,其 
Name
 列中至少有一个词以前辍 chain 开头
USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE CONTAINS(Name, ' "Chain*" ');
GO

6.2 实例

  表数据100万条,
  title类似于文章的标题,
  Description是内容也是全文索引字段

方案1:like,测试后果断排除

方案2:直接使用全文搜索进行,排序消耗大。

方案3:由于查询需要对Title进行排序,建Title字段的倒序索引包含其它字段,最后选择该方案(创建Title字段的倒序索引很重要)。

--给出部分字段
CREATE TABLE [dbo].[Housetest](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Title] [varchar](200) NULL,
    [Description] [nvarchar](max) NOT NULL,
    [IsOnline] [tinyint] NOT NULL,
 CONSTRAINT [PK_Housetest] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
 

创建索引

CREATE INDEX IX_Housetest ON Housetest
(Title DESC
)
INCLUDE
(ID,
Description,
IsOnline
)

查询Description包含“美园”,并且如果Title是“美园”则排在第一位,并且以分页的形式显示,每页20条记录。

select  * from (SELECT  ROW_NUMBER() OVER(Order by (case when Title='美园' Then 1 Else 0 End) desc ) as RowsNumber,ID,Title,Description
  From Housetest
  Where  contains(Description,'美园') and IsOnline=1) tab1 
 where RowsNumber between 1 and 20

七、总结

全文索引功能类似于百度的搜索引擎,但是百度这类搜索引擎有自己的数据字典,在关键字表中对关键字进行排序,保存关键字对应的 文档id,一个文档只会保留很少的关键字,就跟平时写文章要添加标签一样,一般一篇文章就几个标签,当搜索的时候匹配的速度就会非常快,这就需要一个很完善的数据字典表。

全文搜索还有另外的一个功能就是FileStream,需要添加文件流,在服务中启用该功能可以在字段中将文档以二进制的形式保存在字段当中,这样大型文档也可以随数据库一起备份,很多网站存储图片都是存储图片的路径,这样备份数据库的时候图片不会一起备份。

全文索引带来好处的同时也会对性能有一定的影响,特别是在进行筛选操作的时候对服务器性能会带来影响,所以选择一个功能的同时需要考虑对性能带来的影响。 

参考/转载

sqlserver如何添加全文索引 - 锋齐叶落 - 博客园在SQL Server 中提供了一种名为全文索引的技术,可以大大提高从长字符串里搜索数 据的速度,不用在用LIKE这样低效率的模糊查询了。 在SQL Server 中提供了一种名为全文索引的技术,可以https://www.cnblogs.com/qianzf/p/7131741.html

SQL Server 使用全文索引进行页面搜索_沉寂的石头-CSDN博客标签:SQL SERVER/MSSQL SERVER/数据库/DBA/全文索引概述  全文引擎使用全文索引中的信息来编译可快速搜索表中的特定词或词组的全文查询。全文索引将有关重要的词及其位置的信息存储在数据库表的一列或多列中。全文索引是一种特殊类型的基于标记的功能性索引,它是由 SQL Server 全文引擎生成和维护的。生成全文索引的过程不同于生成其他类型的索引。全文引擎并非基于https://blog.csdn.net/chast_cn/article/details/50910827

sqlserver 全文索引 查询使用规则_weixin_41301898的博客-CSDN博客_sqlserver全文索引具体 sqlserver 建立 全文索引 百度一下 很多 这里 补缀描述(要选择好语言环境)CONTAINS andFREETEXT区别:SELECT id, name FROM TeacherWHERE CONTAINS(note, 'heard')SELECT id, name FROM TeacherWHERE FREETEXT(note, 'heard')这...https://blog.csdn.net/weixin_41301898/article/details/89373214

SqlServer 全文索引创建及测试_公众号:SQLServer-CSDN博客_sqlserver 全文索引创建--创建测试表--DROP TABLE FullTextIndexingCREATE TABLE FullTextIndexing(ID INT IDENTITY(1,1) NOT NULL,Sentence VARCHAR(MAX))--创建聚集索引ALTER TABLE FullTextIndexing ADD CONSTRAINT PK_FullTextIndexhttps://blog.csdn.net/kk185800961/article/details/45021471

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

cplvfx

客官,1分钱也是爱,给个赏钱吧

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值