使用 Microsoft® SQL™ Server 2000 的全文搜索功能,可以对在非结构化文本数据上生成的索引执行快速、灵活的查询。常用的全文搜索工具是网站的搜索引擎。为了帮助读者理解全文搜索功能的最佳使用方法,本文介绍了大量抽象概念;并对优化全文索引和查询以实现最大吞吐率和最佳性能,提供了几点提示和技巧。 全文搜索功能简介
全文搜索功能在 SQL Server 7.0 中引入。全文搜索的核心引擎建立在 Microsoft Search (MSSearch) 技术上,Microsoft Exchange 和 Microsoft SharePoint™ Portal Server 等产品中也采用了此项技术。
SQL Server 7.0 全文搜索中公开的功能可提供基本的文本搜索功能,并使用早期版本的 MSSearch;而 SQL Server 2000 的全文搜索实现则包含一组可靠的索引和查询功能,并在 SQL Server 7.0 的基础之上添加了几项增强功能。这些增强功能包括:通过 Microsoft 群集服务完全支持群集操作,能够过滤和索引 IMAGE 列中存储的文档,提供改进的语言支持,以及在性能、可缩放性和可靠性方面进行了改进。
MSSearch 生成、维护和查询文件系统中(而不是 SQL Server 中)存储的全文索引。MSSearch 进行全文索引时使用的逻辑和物理存储单元是目录。全文目录在每个数据库中包含一个或多个全文索引 - 可以为 SQL Server 中的每个表创建一个全文索引,且索引中可以包含该表中的一列或多列。每个表只能属于一个目录,且每个表只能创建一个索引。我们将简单介绍有关组织全文目录和索引的最佳方案 - 但首先,让我们来简单了解一下全文搜索的工作原理。 配置全文搜索功能
要为 SQL Server 中存储的文本数据创建全文索引,应该先完成以下几步准备工作。第一步是以全文方式启用包含要生成索引的文本数据的数据库(如果您尚未执行此操作)。
接下来,您需要创建全文目录,以存储全文索引。正如前面所提到的,此目录中的数据存储在文件系统中(而不是 SQL Server 中),因此,在考虑全文目录的存储位置时应该仔细选择。除非指定其他位置,否则全文目录将存储在 FTDATA 目录(位于 Microsoft SQL ServerMSSQL 存储位置中)的子目录中。以下是在非默认位置创建全文目录的方法:
如果可能的话,最好在其所在的物理驱动器上创建全文目录。如果生成全文索引的进程需要进行大量的 I/O 操作(具体而言,就是从 SQL Server 中读取数据,然后向文件系统写入索引),则应避免使 I/O 子系统成为瓶颈。
那么,全文目录有多大呢?通常情况下,全文目录的系统开销比 SQL Server 中存储的数据(对其进行全文索引)量高出大约 30%;但是,此规则取决于数据中唯一单词(或主键)的分布,以及被您视为是干扰词的单词的分布。干扰词(或终止词)是指要排除在全文索引和查询以外的词语(因为它们不是您感兴趣的搜索词,而且出现频率很高,所以只会使索引变得很大,而不会有实际效果)。稍后,我们将介绍有关干扰词选择方面的注意事项,以及如何优化干扰词以改善查询性能。
对于分页显示结果,我曾见过多种方法,但没有一种方法能够做到百分之百有效。我所推荐的方法可以最大程度地减少全文查询执行的次数(实际上,对于要分页显示的每个结果集只需执行一次),并将 Web 服务器用作一个简单的缓存。从更高的层面来讲,您只需在全文查询中检索一个完整的主键和排位值行集合(如果需要,可以在架构中使用最佳选择并提取常用过滤器),并将其存储在 Web 服务器的内存中(这取决于您的应用程序和负载,想象将 <32 字节的典型主键大小与 <4 字节的排位大小相加 [等于 <36 字节],然后乘以通常返回的结果集 <1000 行,最后等于 <35K。假定一个在任何给定时间返回 <1000 个活动查询结果集中的一个活动缓存集,您将发现此活动缓存集在 Web 服务器上占用的内存少于 35MB - 这还可以接受)。
为了分页显示结果,该进程只遍历 Web 服务器的内存中存储的数组,并对 SQL Server 发出 SELECT 以便只显示需要显示的行和列。这又回到了全文查询仅返回主键和排位的概念中 - SELECT(甚至许多这样的查询语句)比全文查询的速度快许多倍。使用 SELECT 而不是与基表合并多个行,并结合多个其他策略,您可以保留 SQL Server 计算机上更多的 CPU 周期,并且更有效、更划算地利用 Web 领域。
另一种可以替代 Web 服务器端缓存的方法是在 SQL Server 自身中缓存结果集,并定义多种用于浏览这些结果的方法。虽然本文着重说明 Web 服务器 (ASP) 级别的应用程序设计,但 SQL Server 的可编程功能还为生成高性能的 Web 搜索应用程序提供了强大的框架。 小结
Microsoft SQL Server 2000 的全文搜索功能为索引和查询数据库中存储的非结构化文本数据提供了可靠、快速而灵活的方法。如果要广泛地将这种快速、准确的搜索功能应用于各种应用程序,那么很有必要充分利用其速度和精确性,来实现全文搜索解决方案。通过分布计算负载并通过某些巧妙的方式对数据进行组织,可以省下钱来购买其他硬件和软件,以摆脱因不必要的缓慢查询带来的困扰。在开发优秀的搜索应用程序时,通常要考虑到许多因素和注意事项,希望本文提供的信息和示例对您学习使用 SQL Server 2000 生成出色的 Web 搜索应用程序会有所帮助。 附录 A:实现全文搜索功能的最佳选择
改进全文查询性能和有效性的一种可行方法是实现“最佳选择”系统。此系统是一种很简单的方法,可确保某些与特定查询表达式匹配的行先于其他行返回。最佳选择没有复杂的预编程逻辑(例如,SharePoint Portal Server 就包含这样的逻辑),因此,通常是首选办法。
Dim firstRow ' 分页显示行时的第一行 Dim lastRow ' 分页显示行时的最后一行 Dim pageSize ' 页面大小(每次的行数) Dim cn ' 连接对象 Dim rs ' FT 主键/排位返回的结果集(重复使用) Dim useCache ' 使用缓存或命中 FT(0:不使用;1:使用) Dim alldata ' 要缓存的结果行集合 Dim bbdata ' 要缓存的最佳选择行集合 Dim connectionString ' SQL 连接字符串 ' 确定是否要从缓存获取数据 ' 默认为否,否则接受传入的数据 if (request.Form("useCache") <>"") then useCache = request.Form("useCache") elseif (request.QueryString("useCache") <>"") then useCache = request.QueryString("useCache") else useCache =0 endif
Dim p ' 循环通过行时的计数器 Dim numRows ' 缓冲/结果集中的总行数 if (useCache <>"1") then' 获取最佳选择/结果并将其缓存 Dim queryArg ' 传入的查询词 if (request.Form("searchTerm") <>"") then queryArg = request.Form("searchTerm") elseif (request.QueryString("searchTerm") <>"") then queryArg = request.QueryString("searchTerm") else response.Write("未提供搜索词"& VbCrLF) exitsub endif
' 在此获取要使用的行范围 if (request.Form("firstRow") <>"") then firstRow = request.Form("firstRow") lastRow = firstRow+pageSize elseif (request.QueryString("firstRow") <>"") then firstRow = request.QueryString("firstRow") lastRow = firstRow+pageSize endif
endif' useCache<>TRUE ' 对于本应用程序,只是打印出所有最佳选择 ' (可能比页面大小大),然后分页显示普通结果 ' 此处假设:在使用缓存时,如果没有新的最佳选择, ' 则使用以前显示的最佳选择 ifnot(IsEmpty(bbdata)) then response.Write("最佳选择:"& VbCrLf) for p =0toubound(bbdata, 2) response.Write(bbData(0,p) &""& bbData(1,p) & VbCrLf) next response.Write(VbCrLf) endif
' 返回搜索结果(可能只有最佳选择) ifnot(IsEmpty(alldata)) then ifuBound(alldata, 2) < lastRow then lastRow =uBound(allData, 2) endif
response.Write("搜索结果:"& VbCrLf)
for p = firstRow to lastRow response.Write(allData(0,p) &""& allData(1,p) & VbCrLf) next endif' not(IsEmpty(alldata)) End Sub
'----------------------------------------------------------------' ' 关闭并清除连接对象 ' '----------------------------------------------------------------' PrivateSub ConnClose rs.Close Set rs =Nothing cn.Close Set cn =Nothing End Sub
正如以上两个代码示例所示,创建可执行有效全文查询(用最佳选择完成)并缓存和分页显示结果的 Web 应用程序,并不需要花费太多的工夫。只需使用最低的系统开销,即可添加用于提供其他数据、增强最佳选择的外观以及在搜索结果中导航的逻辑(此外,强烈建议您实现其他用于错误处理、安全设置和清理传入数据的严密逻辑)。
通过上面的高级建议和示例,使用 SQL Server 2000 全文搜索设计和实现快速可缩放的 Web 搜索应用程序就是轻而易举的事情了。 附录 C:资源
Full-Text Search Deployment(英文)
是那些初次接触全文搜索的用户的最佳参考。介绍了填充方法及硬件和软件需求,并为使用 SQL Server 2000 全文搜索提供了提示、技巧和其他文档。
全文搜索公共新闻组 (microsoft.public.sqlserver.fulltext)
查找有关全文搜索问题的答案以及有用提示和技巧的理想场所。全文搜索新闻组是 SQL Server 开发小组和博学的 Microsoft MVP 成员经常光顾的场所。