SQL Server FullText解决Like字句性能问题

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: # 场景引入 这天老鸟火急火燎的冲到菜鸟座位:“还记得你在云栖社区发表的一篇名为‘SQL Server利用HashKey计算列解决宽字段查询的性能问题’的文章吗?被人踢馆啦,人家觉得你这个限制条件太苛刻,只能解决完全等于的问题条件下的性能问题,没有太大的现实意义。” 菜鸟烧脑的调动大脑的每一个细胞:“哦,你说的是这篇文章啊?”。 [SQL Server利用HashKey计算列解决宽字段查

场景引入

这天老鸟火急火燎的冲到菜鸟座位:“还记得你在云栖社区发表的一篇名为‘SQL Server利用HashKey计算列解决宽字段查询的性能问题’的文章吗?被人踢馆啦,人家觉得你这个限制条件太苛刻,只能解决完全等于的问题条件下的性能问题,没有太大的现实意义。”
菜鸟烧脑的调动大脑的每一个细胞:“哦,你说的是这篇文章啊?”。

SQL Server利用HashKey计算列解决宽字段查询的性能问题

问题分析

菜鸟反思着,的确,需要完全匹配这个条件限制太严格了,SQL Server有没有一种方法来代替LIKE字句的功能而又可以大大提高查询效率的呢?因为,我们知道,LIKE左模糊匹配是可以使用到索引,而右模糊和完全模糊匹配是完全无法使用到索引的。G哥告诉菜鸟有解决方法,用FullText搜索啊。据说阿里云RDS SQL Server 2008和ECS 版RDS SQL 2012都支持SQL Server的FullText哦,对于使用阿里云RDS SQL Server的用户真是个好消息。

解决方法

来看我们的一个简单测试。

创建测试对象

USE master
GO
IF DB_ID('test') IS NULL
    CREATE DATABASE Test;
GO

use test
go

--in order to check fulltext enable or not.
SELECT is_fulltext_enabled,*
FROM sys.databases
WHERE name = DB_NAME()
;

IF OBJECT_ID('dbo.Item','u') IS NOT NULL
BEGIN
    TRUNCATE TABLE dbo.Item
    DROP TABLE dbo.Item
END
GO

CREATE TABLE dbo.Item
(
id int identity(1,1) primary key
,item_number int not null
,item_desc varchar(4000) null
);
GO

--fulltext unique index creating
CREATE UNIQUE INDEX uix_item_number ON dbo.Item(item_number);

--fulltext catelog creating
IF NOT EXISTS(
        SELECT * FROM sys.fulltext_catalogs WITH(NOLOCK)
        WHERE name = N'ftxt_Item')
BEGIN
    CREATE FULLTEXT CATALOG ftxt_Item AS DEFAULT;
END;

--create fulltext index 
CREATE FULLTEXT INDEX ON dbo.Item(item_desc) 
KEY INDEX uix_item_number 
ON ftxt_Item;
GO
AI 代码解读

初始化数据

--testing table data init.
DECLARE
    @do int
    ,@loop int
    ,@item_desc varchar(4000)
;

SELECT
    @do = 1
    ,@loop = 100000
    ,@item_desc = ''
;

SET NOCOUNT ON
WHILE @do <= @loop
BEGIN
    set 
        @item_desc = REPLICATE(newid(),112)
    ;
    INSERT INTO dbo.Item
    SELECT CHECKSUM(@item_desc),@item_desc;

    SET @do = @do + 1;
END;
GO
AI 代码解读

创建索引失败

想要在超过900byte宽度的字段上创建索引,门都没有,SQL Server直接报错。

--try to create index on item_desc:error occurs when data inited
CREATE INDEX ix_item_desc ON dbo.Item(item_desc);
AI 代码解读

错误信息

Warning! The maximum key length is 900 bytes. The index 'ix_item_desc' has maximum length of 4000 bytes. For some combination of large values, the insert/update operation will fail.
Msg 1946, Level 16, State 3, Line 1
Operation failed. The index entry of length 4000 bytes for the index 'ix_item_desc' exceeds the maximum length of 900 bytes.
The statement has been terminated.
AI 代码解读

LIKE查询和Fulltext查询

--===testing performance bewteen like & fulltext
declare
    @item_desc varchar(10)
;

SELECT TOP 1 @item_desc = LEFT(item_desc, 10)
FROM dbo.Item WITH(NOLOCK) 
WHERE id = 2012;

SET STATISTICS PROFILE ON
SET STATISTICS TIME ON
SET STATISTICS IO ON

SELECT *
FROM dbo.Item WITH(NOLOCK)
WHERE item_desc like @item_desc+'%'

SELECT *
FROM dbo.Item WITH(NOLOCK)
WHERE item_desc like '%'+@item_desc+'%'

SELECT * 
FROM dbo.Item WITH(NOLOCK)
WHERE CONTAINS(item_desc,@item_desc)

SET STATISTICS TIME OFF
SET STATISTICS IO OFF
SET STATISTICS PROFILE OFF
GO
AI 代码解读

执行计划对比

非常有意思了,执行计划对比来看,Like左匹配和完全模糊匹配均走是Clustered Index Scan,相当于Table Scan;而EstimateRows显示满足条件约为12440行,也暴露出SQL Server执行计划对Like字句的评估并不准确,实际满足条件只有1行而已,所以导致最后的查询效率不高。但是,FullText的执行计划中EstimateRows显示只有1行,与实际情况相符合。
01.png

执行效率对比

对比完执行计划,让我们来看看最后执行效率对比:

  • Like左模糊匹配执行效率: Logical Reads 50185,说明IO读非常高,这是Clustered Index Scan导致的结果;CPU消耗47 ms,总的执行时间51ms。
  • Like完全模糊匹配执行效率:和Like左模糊匹配一样,Logical Reads 50185,也是IO读非常高; CPU 更加离谱达到了4789ms,执行时间4919ms。
  • FullText查询执行效率:Logical Reads仅仅只有5,所以最后CPU消耗为0ms,执行时间50ms。

从这个对比结果来看,FullText完胜LIKE字句,IO读取大大降低,CPU消耗减少,效率得到了很大的提升。

#### Like左模糊匹配执行效率
Table 'Item'. Scan count 1, logical reads 50185, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 47 ms,  elapsed time = 51 ms.

#### Like完全模糊匹配执行效率
Table 'Item'. Scan count 1, logical reads 50185, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 4789 ms,  elapsed time = 4919 ms.

#### FullText查询执行效率
Informational: The full-text search condition contained noise word(s).
Table 'Item'. Scan count 0, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 50 ms.
AI 代码解读

写在最后

完成上面的测试,菜鸟有了对老鸟和“踢馆者”合理的交代,那就是使用FullText来解决Like语句的性能问题吧。

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
打赏
0
0
0
1
9296
分享
相关文章
|
24天前
|
SQL
【YashanDB知识库】like 变量的SQL语句应用程序执行效率低与yasql执行效率高
【YashanDB知识库】like 变量的SQL语句应用程序执行效率低与yasql执行效率高
如何优化SQL查询以提高数据库性能?
这篇文章以生动的比喻介绍了优化SQL查询的重要性及方法。它首先将未优化的SQL查询比作在自助餐厅贪多嚼不烂的行为,强调了只获取必要数据的必要性。接着,文章详细讲解了四种优化策略:**精简选择**(避免使用`SELECT *`)、**专业筛选**(利用`WHERE`缩小范围)、**高效联接**(索引和限制数据量)以及**使用索引**(加速搜索)。此外,还探讨了如何避免N+1查询问题、使用分页限制结果、理解执行计划以及定期维护数据库健康。通过这些技巧,可以显著提升数据库性能,让查询更高效流畅。
云原生数据仓库AnalyticDB PostgreSQL同一个SQL可以实现向量索引、全文索引GIN、普通索引BTREE混合查询,简化业务实现逻辑、提升查询性能
本文档介绍了如何在AnalyticDB for PostgreSQL中创建表、向量索引及混合检索的实现步骤。主要内容包括:创建`articles`表并设置向量存储格式,创建ANN向量索引,为表增加`username`和`time`列,建立BTREE索引和GIN全文检索索引,并展示了查询结果。参考文档提供了详细的SQL语句和配置说明。
51 1
如何在 Oracle 中配置和使用 SQL Profiles 来优化查询性能?
在 Oracle 数据库中,SQL Profiles 是优化查询性能的工具,通过提供额外统计信息帮助生成更有效的执行计划。配置和使用步骤包括:1. 启用自动 SQL 调优;2. 手动创建 SQL Profile,涉及收集、执行调优任务、查看报告及应用建议;3. 验证效果;4. 使用 `DBA_SQL_PROFILES` 视图管理 Profile。
|
5月前
|
SQL性能提升秘籍:5步优化法与10个实战案例
在数据库管理和应用开发中,SQL查询的性能优化至关重要。高效的SQL查询不仅可以提高应用的响应速度,还能降低服务器负载,提升用户体验。本文将分享SQL优化的五大步骤和十个实战案例,帮助构建高效、稳定的数据库应用。
327 3
IntelliJ IDEA处理大文件SQL:性能优势解析
在数据库开发和管理工作中,执行大型SQL文件是一个常见的任务。传统的数据库管理工具如Navicat在处理大型SQL文件时可能会遇到性能瓶颈。而IntelliJ IDEA,作为一个强大的集成开发环境,提供了一些高级功能,使其在执行大文件SQL时表现出色。本文将探讨IntelliJ IDEA在处理大文件SQL时的性能优势,并与Navicat进行比较。
80 4
|
5月前
|
如何优化SQL查询性能?
【10月更文挑战第28天】如何优化SQL查询性能?
292 10
惊呆:where 1=1 可能严重影响性能,差了10多倍,快去排查你的 sql
老架构师尼恩在读者交流群中分享了关于MySQL中“where 1=1”条件的性能影响及其解决方案。该条件在动态SQL中常用,但可能在无真实条件时导致全表扫描,严重影响性能。尼恩建议通过其他条件或SQL子句命中索引,或使用MyBatis的`&lt;where&gt;`标签来避免性能问题。他还提供了详细的执行计划分析和优化建议,帮助大家在面试中展示深厚的技术功底,赢得面试官的青睐。更多内容可参考《尼恩Java面试宝典PDF》。
|
5月前
|
SQL性能提升指南:五大优化策略与十个实战案例
在数据库性能优化的世界里,SQL优化是提升查询效率的关键。一个高效的SQL查询可以显著减少数据库的负载,提高应用响应速度,甚至影响整个系统的稳定性和扩展性。本文将介绍SQL优化的五大步骤,并结合十个实战案例,为你提供一份详尽的性能提升指南。
143 0
慢SQL对数据库写入性能的影响及优化技巧
在数据库管理系统中,慢SQL(即执行缓慢的SQL语句)不仅会影响查询性能,还可能对数据库的写入性能产生显著的不利影响

热门文章

最新文章