SQL Server 2005全文检索技术在网站上的应用实录(二)
2009-09-25 11:17
507 查看
或者键入如下命令:
b)选择或创建新的索引目录。
c)定义填充计划。
至此,表的全文索引已经建立完毕,表示只要键入SQL 指令就可以完成全文检索功能。
第三步,开发存储过程并把结果集分页,以供前台页面调用返回查询的结果。
1) 建立找资本全文检索储存过程USP_CaptialInfo_FullIndex。
2)建立通用分页存过程[USP_GetFrontDataList_ByFullIndex]。由于性能考虑,返回给前台页面需要网站数据库端即完成分页。
由于本行业网站可以提高如下几类信息资源,现列表分示如下:
五、全文检索性能考量
除了硬件资源 [如内存(3GB 限制)、磁盘速度和 CPU 速度] 以外,全文搜索性能还受到 Microsoft SQL Server 和 Microsoft Full-Text Engine for SQL Server (MSFTESQL) 服务对这些资源的争用情况的影响。MSFTESQL 服务只对磁盘进行写操作,而 SQL Server 会对磁盘进行读写操作。从性能角度出发,关键是很好地优化 MSFTESQL 服务,以便获得最佳使用效果。
全文搜索性能包含两个方面:
◆全文索引性能
◆全文查询性能
全文索引性能
Microsoft SQL Server 2005 中的全文搜索的索引性能很大程度上取决于下面两个因素:
◆SQL Server 创建全文批花费的时间。
◆MSFTESQL 服务使用这些批的速度。
若要达到最佳性能,需要优化 SQL Server 与 MSFTESQL 服务之间的交互。如果 MSFTESQL 服务处理不完 SQL Server 生成的批,该服务将暂停,并生成一个爬网日志消息来指示此暂停状态。有关如何解决此问题的信息,请参阅Microsoft SQL Server 全文引擎 (MSFTESQL) 服务已暂停。
另一方面,如果 SQL Server 没有生成足够的全文批, 使 MSFTESQL 服务充分运行,该服务就会闲置,这样就不能达到最佳性能。若要确保 MSFTESQL 服务处于最佳使用状况,需要跟踪并优化下列计数器:
正在处理的批计数器 - Microsoft Full-Text Engine Filter Daemon (MSFTELFD)
此计数器应当等于系统中的 CPU 数或其两倍。当 CPU 使用值为 0、1 或 2 时,指示 SQL Server 执行情况不好。例如,如果计算机上具有 4 个 CPU,此数值就应该为 4 或 8。
已就绪的批队列 - MSFTESQL 服务
如果批数较少,可以执行下列操作:
◆增加全文批的大小。
◆确保基表具有聚集索引。
◆将 SQL 日志、数据库文件和全文目录分别放在单独的磁盘上。
◆默认情况下,全文批的大小是每批 1600 行。如果计算机上有八个频率为 700Mhz 的 CPU,推荐采用的批大小为 5000 行。
注意:
增加批大小会导致批的生成速度变慢,而且 MSFTSQL 要执行更多的操作来处理每个批。此外,请记住全文批的大小受共享内存区域大小的限制。共享内存区域大小的默认值为 4Mb。
爬网范围
◆使用 sp_configure 最大全文爬网范围选项增大爬网范围计数器。理想情况下,此值应该是 CPU 数的两倍。
◆使用 UPDATE STATISTICS 语句更新基表的统计信息。
提高全文查询性能的建议
下面列出了有助于提高全文查询性能的建议。
使用 ALTER INDEX REORGANIZE 对基表的索引进行碎片整理。
使用 ALTER FULLTEXT CATALOG REORGANIZE 重新组织全文目录。切记要在进行性能测试之前执行此操作,因为它会引起该目录中全文索引的主合并。
仅选择较小的列作为全文键列。即使支持 900 字节的列,也不建议您使用这么大的键列来创建全文索引。
将多个 CONTAINS 合并为一个 CONTAIN。在 Microsoft SQL Server 中,您可以在 CONTAINS 查询中指定一个包含若干列的列表。
如果只需要全文键或排名的信息,请分别使用 CONTAINSTABLE 或 FREETEXTTABLE,而不要使用 CONTAINS 或 FREETEXT。
使用 FREETEXTTABLE 和 CONTAINSTABLE 语法的 TOP_N_BY_RANK 选项来限制结果数并提高性能。如果您不是对可能查询到的所有信息都感兴趣,可使用此选项。
六、需求规划
我们知道做好网站检索不仅仅面临纯技术的问题,而且本身需要事前的需求规划,这里给出了全网搜索在功能性需求和非功能性需求上的典型需求。
功能性的需求:
(1)哪些业务数据需要提供全文的检索服务?
(2)这些业务数据中那些关键信息是业务人员关心的?
(3)需要支持哪些国家的语言?
(4)有哪些行业术语、常用缩略词、替换词?
(5)需要哪些检索功能,分别基于什么范畴的关键字展开检索?
非功能性的需求:
(1)业务上以前是否尝试过关系数据库查询、多维数据分析解决手头的问题?
(2)检索时效性要求。
(3)习惯的检索操作平台(浏览器 / 桌面),查询结果的展示方式。
(4)授权控制。
(5)查询结果的导出和发布方式要求。
七、结束语
本文提供了网站如何设计和实现基于SQL Server 2005的全文检索实例,希望能对正在使用SQL Server 2005构建网站搜索的同仁有所裨益。
CREATE FULLTEXT INDEX ON TableName KEY INDEX PK_IndexName ON DB WITH CHANGE_TRACKING AUTO ALTER FULLTEXT INDEX ON TableName ADD ColumnName |
![]() |
图7 |
![]() |
图8 |
第三步,开发存储过程并把结果集分页,以供前台页面调用返回查询的结果。
1) 建立找资本全文检索储存过程USP_CaptialInfo_FullIndex。
/* 找资本全文索引开发过程 */ CREATE PROCEDURE USP_CaptialInfo_FullIndex ( @TableViewQueryName Varchar( 1024 ), --传入的查询字符窜 @SearchKeyword nvarchar(100), --传入的查询关键字 @SelectStr Varchar( 500 ), --选择列字符串 @Criteria Varchar( 8000 ), --查询条件 @Sort Varchar( 255 ), --排序字符串 @FristTopNum int, --显示的第一页置顶的数目 @Page bigint OUTPUT , --显示的当前页号 @CurrentPageRow bigint, --页大小(显示多少行) @TotalCount bigint output, --通过该查询条件,返回的查询记录的总页数 @Totaltimes bigint output --所有搜索时间,以秒为单位 ) as DECLARE @starttime datetime, @endtime datetime SELECT @starttime = getdate() IF ISNULL(@SearchKeyword,'') !='' OR RTRIM(@SearchKeyword)!='' BEGIN SET @TableViewQueryName = ' SELECT '+ ' ROW_NUMBER() OVER (ORDER BY RANK DESC) AS SerialNumber ,'+ ' F.[rank], '+ ' p.*' + ' FROM '+ ' FREETEXTTABLE( CapitalInfoFactTab , (ProvinceName, CityName, CountyName, Keyword,Title ,IndustryBName , shortcontent, ComAbout , ComBreif) , '+ ''''+@SearchKeyword+ ''''+') AS f '+ ' INNER JOIN CapitalInfoFactTab AS p '+ ' ON f.[key] = p.infoID ' EXEC [USP_GetFrontDataList_ByFullIndex] @TableViewQueryName, @SearchKeyword, @SelectStr, @Criteria, @Sort, @FristTopNum, @Page OUTPUT , @CurrentPageRow , @TotalCount OUTPUT END ELSE BEGIN EXEC dbo.GetFrontDataList 'dbo.ProjectInfoFactTab', 'InfoID', @SelectStr,@Criteria,@Sort,0, @Page output, @CurrentPageRow, @TotalCount output END SELECT @endtime = getdate() SELECT @Totaltimes = DATEdiff(Ms, @starttime ,@endtime) RETURN |
CREATE PROCEDURE [dbo].[USP_GetFrontDataList_ByFullIndex] ( @TableViewQueryName Varchar( 1024 ), --Table或View或者Query的名字或字符串 @Key Varchar( 50 ), --关键字 @SelectStr Varchar( 500 ), --选择列字符串 @Criteria Varchar( 8000 ),--查询条件 @Sort Varchar( 255 ), --排序字符串 @FristTopNum INT, --显示的第一页置顶的数目 @Page BIGINT OUTPUT, --显示的当前页号 @CurrentPageRow BIGINT, --页大小(显示多少行) @TotalCount BIGINT OUTPUT --通过该查询条件,返回的查询记录的总页数 ) AS SET NOCOUNT ON if charindex(';',@Criteria)>0 or charindex('--',@Criteria)>0 or charindex('/*', @Criteria)>0 or charindex('*/',@Criteria)>0 or charindex('syscolumns',@Criteria)>0 or charindex('sysfiles',@Criteria)>0 or charindex('char(124)',@Criteria)>0 or charindex('1=1',@Criteria)>0 RETURN DECLARE @TotalStr nVarchar(4000) DECLARE @Str nVarchar(4000) DECLARE @TopRowNum bigint IF @SelectStr IS NULL AND RTRIM(LTRIM(@Criteria)) = '' SET @SelectStr = '*' IF @FristTopNum IS NULL AND @FristTopNum < 0 BEGIN SET @FristTopNum = 0 END ELSE IF @FristTopNum > @CurrentPageRow BEGIN SET @FristTopNum = @CurrentPageRow END IF @CurrentPageRow > 0 BEGIN IF @Criteria IS NOT NULL AND RTRIM(LTRIM(@Criteria)) <> '' BEGIN SET @TotalStr = 'SELECT @TotalCount=COUNT(*) FROM ' + '('+ @TableViewQueryName +')'+ ' T ' + ' WHERE ' + @Criteria END ELSE BEGIN SET @TotalStr = 'SELECT @TotalCount=COUNT(*) FROM ' + '('+@TableViewQueryName +')'+ ' T ' END PRINT @TotalStr EXEC sp_ExecuteSql @TotalStr, N'@TotalCount bigint output',@TotalCount output SET @TotalCount = @TotalCount + isnull(@FristTopNum ,0) DECLARE @TotalPage bigint SET @TotalPage = @TotalCount/@CurrentPageRow IF @TotalCount%@CurrentPageRow > 0 BEGIN SET @TotalPage = @TotalPage + 1 END IF @Page <= 0 BEGIN SET @Page = 1 END IF @TotalPage > 0 AND @Page > @TotalPage BEGIN SET @Page = @TotalPage END --组织查询语句 SET @Str = 'SELECT ' + @SelectStr + ' FROM (' + @TableViewQueryName + ') T WHERE T.SerialNumber >' + cast ((@Page-1) as varchar(10)) + '*' +cast( @CurrentPageRow as varchar(10))+ ' AND T.SerialNumber <= '+ cast (@Page as varchar(10)) + '*' +cast( @CurrentPageRow as varchar(10)) IF @Sort IS NOT NULL ANDRTRIM(LTRIM(@Sort)) <> '' BEGIN IF @Criteria IS NOT NULL AND RTRIM(LTRIM(@Criteria)) <> '' BEGIN SET @Str = @Str + ' AND (' + @Criteria + ') ORDER BY '+@Sort END ELSE BEGIN SET @Str = @Str + ' AND (' + @Criteria + ') ORDER BY '+@Sort END END ELSE BEGIN IF @Criteria IS NOT NULL AND RTRIM(LTRIM(@Criteria)) <> '' BEGIN SET @str = @str + ' AND (' + @Criteria + ') ' END END --对无记录时当前页数的处理 IF @TotalCount=0 BEGIN SET @Page = 0 END END EXEC sp_ExecuteSql @Str [/code] |
ID | 检索内容 | 数据表 | 检索命令示例 |
1 | 投资 | CapitalInfoTab | DECLARE @RC int |
DECLARE @TableViewQueryName varchar(1024) | |||
DECLARE @SearchKeyword nvarchar(100) | |||
DECLARE @SelectStr varchar(500) | |||
DECLARE @Criteria varchar(8000) | |||
DECLARE @Sort varchar(255) | |||
DECLARE @FristTopNum int | |||
DECLARE @Page bigint | |||
DECLARE @CurrentPageRow bigint | |||
DECLARE @TotalCount bigint | |||
DECLARE @Totaltimes bigint | |||
-- TODO: 在此处设置参数值。 | |||
SET @SearchKeyword = '地产项目' | |||
SET @SelectStr = '*' | |||
SET @Sort = '' | |||
SET @Page= 1 | |||
SET @CurrentPageRow = 20 | |||
EXECUTE @RC = [InvestDM].[dbo].USP_CapitalInfo_FullIndex | |||
@TableViewQueryName | |||
,@SearchKeyword | |||
,@SelectStr | |||
,@Criteria | |||
,@Sort | |||
,@FristTopNum | |||
,@Page | |||
,@CurrentPageRow | |||
,@TotalCount OUTPUT | |||
,@Totaltimes OUTPUT | |||
SELECT @Page,@TotalCount,@Totaltimes | |||
2 | 融资 | ProjectInfoTab | DECLARE @SearchKeyword nvarchar(100) --传入的查询关键字 |
SET @SearchKeyword = '深圳' | |||
SELECT p.title, | |||
p.infoid, | |||
f.[rank] , | |||
keyword,title,provinceName,cityName,CountyName | |||
FROM | |||
FREETEXTTABLE([ProjectInfoFactTab], (provinceName,cityName,CountyName,keyword,title), @SearchKeyword) AS f | |||
INNER JOIN [ProjectInfoFactTab] AS p | |||
ON f.[key] = p.infoID | |||
ORDER BY RANK DESC | |||
3 | 招商 | MerchantInfoTab | DECLARE @SearchKeyword nvarchar(100) --传入的查询关键字 |
SET @SearchKeyword = '深圳' | |||
SELECT | |||
ROW_NUMBER() OVER (ORDER BY RANK DESC) AS SerialNumber , | |||
F.[rank], | |||
p.* | |||
FROM | |||
FREETEXTTABLE( MerchantInfoFactTab , (ProvinceName, CityName, CountyName, Keyword, | |||
Title ,IndustryBName , shortcontent, ZoneAbout , ZoneAboutBrief, MerchantTypeName ,MerchantAttributeName, CooperationDemandName ) , @SearchKeyword) AS f | |||
INNER JOIN MerchantInfoFactTab AS p | |||
ON f.[key] = p.infoID | |||
4 | 资讯 | NewsTab | DECLARE @SearchKeyword nvarchar(100) --传入的查询关键字 |
SET @SearchKeyword = '深圳' | |||
SELECT | |||
ROW_NUMBER() OVER (ORDER BY RANK DESC) AS SerialNumber , | |||
F.[rank] , | |||
p.* | |||
FROM | |||
FREETEXTTABLE( NewsInfoFactTab , (AreaName, Keyword, | |||
Title , DisplayTitle, subtitle ,Summary , Content ,NewsIndustryName , NewsTypeName ) , @SearchKeyword ) AS f | |||
INNER JOIN NewsInfoFactTab AS p | |||
ON f.[key] = p.infoID |
除了硬件资源 [如内存(3GB 限制)、磁盘速度和 CPU 速度] 以外,全文搜索性能还受到 Microsoft SQL Server 和 Microsoft Full-Text Engine for SQL Server (MSFTESQL) 服务对这些资源的争用情况的影响。MSFTESQL 服务只对磁盘进行写操作,而 SQL Server 会对磁盘进行读写操作。从性能角度出发,关键是很好地优化 MSFTESQL 服务,以便获得最佳使用效果。
全文搜索性能包含两个方面:
◆全文索引性能
◆全文查询性能
全文索引性能
Microsoft SQL Server 2005 中的全文搜索的索引性能很大程度上取决于下面两个因素:
◆SQL Server 创建全文批花费的时间。
◆MSFTESQL 服务使用这些批的速度。
若要达到最佳性能,需要优化 SQL Server 与 MSFTESQL 服务之间的交互。如果 MSFTESQL 服务处理不完 SQL Server 生成的批,该服务将暂停,并生成一个爬网日志消息来指示此暂停状态。有关如何解决此问题的信息,请参阅Microsoft SQL Server 全文引擎 (MSFTESQL) 服务已暂停。
另一方面,如果 SQL Server 没有生成足够的全文批, 使 MSFTESQL 服务充分运行,该服务就会闲置,这样就不能达到最佳性能。若要确保 MSFTESQL 服务处于最佳使用状况,需要跟踪并优化下列计数器:
正在处理的批计数器 - Microsoft Full-Text Engine Filter Daemon (MSFTELFD)
此计数器应当等于系统中的 CPU 数或其两倍。当 CPU 使用值为 0、1 或 2 时,指示 SQL Server 执行情况不好。例如,如果计算机上具有 4 个 CPU,此数值就应该为 4 或 8。
已就绪的批队列 - MSFTESQL 服务
如果批数较少,可以执行下列操作:
◆增加全文批的大小。
◆确保基表具有聚集索引。
◆将 SQL 日志、数据库文件和全文目录分别放在单独的磁盘上。
◆默认情况下,全文批的大小是每批 1600 行。如果计算机上有八个频率为 700Mhz 的 CPU,推荐采用的批大小为 5000 行。
注意:
增加批大小会导致批的生成速度变慢,而且 MSFTSQL 要执行更多的操作来处理每个批。此外,请记住全文批的大小受共享内存区域大小的限制。共享内存区域大小的默认值为 4Mb。
爬网范围
◆使用 sp_configure 最大全文爬网范围选项增大爬网范围计数器。理想情况下,此值应该是 CPU 数的两倍。
◆使用 UPDATE STATISTICS 语句更新基表的统计信息。
提高全文查询性能的建议
下面列出了有助于提高全文查询性能的建议。
使用 ALTER INDEX REORGANIZE 对基表的索引进行碎片整理。
使用 ALTER FULLTEXT CATALOG REORGANIZE 重新组织全文目录。切记要在进行性能测试之前执行此操作,因为它会引起该目录中全文索引的主合并。
仅选择较小的列作为全文键列。即使支持 900 字节的列,也不建议您使用这么大的键列来创建全文索引。
将多个 CONTAINS 合并为一个 CONTAIN。在 Microsoft SQL Server 中,您可以在 CONTAINS 查询中指定一个包含若干列的列表。
如果只需要全文键或排名的信息,请分别使用 CONTAINSTABLE 或 FREETEXTTABLE,而不要使用 CONTAINS 或 FREETEXT。
使用 FREETEXTTABLE 和 CONTAINSTABLE 语法的 TOP_N_BY_RANK 选项来限制结果数并提高性能。如果您不是对可能查询到的所有信息都感兴趣,可使用此选项。
六、需求规划
我们知道做好网站检索不仅仅面临纯技术的问题,而且本身需要事前的需求规划,这里给出了全网搜索在功能性需求和非功能性需求上的典型需求。
功能性的需求:
(1)哪些业务数据需要提供全文的检索服务?
(2)这些业务数据中那些关键信息是业务人员关心的?
(3)需要支持哪些国家的语言?
(4)有哪些行业术语、常用缩略词、替换词?
(5)需要哪些检索功能,分别基于什么范畴的关键字展开检索?
非功能性的需求:
(1)业务上以前是否尝试过关系数据库查询、多维数据分析解决手头的问题?
(2)检索时效性要求。
(3)习惯的检索操作平台(浏览器 / 桌面),查询结果的展示方式。
(4)授权控制。
(5)查询结果的导出和发布方式要求。
七、结束语
本文提供了网站如何设计和实现基于SQL Server 2005的全文检索实例,希望能对正在使用SQL Server 2005构建网站搜索的同仁有所裨益。
相关文章推荐
- SQL Server 2005全文检索技术在网站上的应用实录 索引
- SQL Server 2005全文检索技术在网站上的应用实录
- SQL Server 2005全文检索技术在网站上的应用实录
- 【ZT】SQL Server 2005全文检索技术在网站上的应用实录
- SQL Server 2005全文检索技术在网站上的应用实录
- SQL Server 2005全文检索技术在网站上的应用实录
- SQL Server 2005全文检索技术在网站上的应用实录
- SQL Server 2005全文检索技术在网站上的应用实录(一)
- SQL Server 2005全文检索技术
- SQL Server 2005全文检索技术
- SQL Server 2005全文检索技术
- SQL Server 2005全文检索技术
- SQL Server 2005全文检索技术
- SQL Server 2005全文检索技术
- SQL Server 2005全文检索技术
- SQL Server 2005全文检索技术
- SQL Server 2005全文检索技术
- SQL Server 2005全文检索技术
- SQL Server 2005全文检索技术
- SQL Server 2005全文检索技术