转自Carfield的猫窝
SQL Server全文索引的个人总结(上)
大家都知道LIKE查询很慢,全文索引就是事先做好相关的索引,表示哪个主题词可以在哪些记录里找到,甚至事先计算好RANK,检索时可以把相关度高的先列出来,这可以大大提高检索的速度。
打个比方,你有很多的小抽屉,每个抽屉里面放一些杂物,假如你要找东西,最原始的方法就是一个个抽屉翻,这就是没有索引的情况。
假如聪明一点,给抽屉编号(唯一键),把哪个号码的抽屉有什么东西记录在纸上,找东西先看看这张纸,这就是普通索引,假如你要知道哪个抽屉有什么,你可以在纸上迅速找到抽屉号码(大家知道这是使用查找树),然后得到相关的信息,这种情况普通索引是很快的;但是要找到一个特定的东西哪些抽屉有,你就要把整张纸遍历一次,这就是LIKE查询,假如你要找哪些抽屉同时有2种甚至更多种物品,LIKE就更加繁琐了。假如一个表有上千万的纪录,大家可以想象查询的代价。
可以换一个思路,另外找张纸,记录一样东西存在于哪些抽屉:
夹子:1,3,4,5,6,9,12...
钱币:2,3,4,7,12...
药丸:1,3,5,6...
这样找到某样东西或者某几样东西都很容易。
全文索引和普通的SQL索引有很多的区别:
普通 SQL 索引 | 全文索引 |
存储时受定义它们所在的数据库的控制。 | 存储在文件系统中,但通过数据库管理。 |
每个表允许有若干个普通索引。 | 每个表只允许有一个全文索引。 |
当对作为其基础的数据进行插入、更新或删除时,它们自动更新。 | 将数据添加到全文索引称为填充,全文索引可通过调度或特定请求来请求,也可以在添加新数据时自动发生。 |
不分组。 | 在同一个数据库内分组为一个或多个全文目录。 |
使用 SQL Server 企业管理器、向导或 Transact-SQL 语句创建和除去。 | 使用 SQL Server 企业管理器、向导或存储过程创建、管理和除去。 |
使用全文索引的话,可以看看下面的帖子(感谢大力和lihonggen0):
???? 如何在sqlserver中建立全文索引:
???? http://www.csdn.net/develop/Read_Article.asp?Id=17137
???
???? 如何使用image字段:
???? http://expert.csdn.net/Expert/topic/1594/1594455.xml
发现大家有一个常问的问题,就是关于以下的信息的:
查询子句只包含被忽略的词
这是因为使用一些很简单的词,比如'是',进行查询的缘故。
提出的解决办法不外乎是把C:\Program Files\Microsoft SQL Server\MSSQL\FTDATA\SQLServer\Config\noise.chs 清空
觉得这种方法是不可取的,大家打开这个文件看看,发现里面是一些这样的词:is,are,be,at,我,是
这些词都是频率很高的词,而且在查询中的意义不大,就好像几乎每个抽屉里面都有纸屑一样,为这些词作索引得不偿失,所以全文引擎把这些词称为干扰词不做索引,个人觉得在应用中过滤这些词然后向用户提出友好的提示更好,而不是使用清空noise.chs粗暴的对待全文引擎。比方大家可以看看在Google中搜索“的”
-------------------------------------------------------------------------
另外谢谢ghj,一个很重要的东西遗漏了,与一般的索引立即更新不同,全文索引一般是定期维护索引的,所以对于频繁更新的数据不合适,需要做全文索引的对象一般都是论文网页之类,还算适合拉!
个人觉得我的数据库没有代表性,所以也不细说:作索引的时候,CPU和内存使用都很高,时间也很长(下面我的数据库是整个晚上),完成以后并不需要使用很多的系统资源,多个全文查询并发的时候也有不小的CPU消耗,但是比LIKE强。
我的系统上数据库是123M,太小,使用全文索引没有感到特别的优势,但是可以想想对于GOOGLE那样的海量数据,使用LIKE是不可想象的:)当然别人也没有使用关系数据库。
SQL Server全文索引的个人总结(下)-关于中文分词
在使用SQL Search的过程中,还发现了一个问题:它对中文,是按字分词的,下面我解释一下:
比如对'博客堂成员很多是MVP'这句话,假如一个个的字的作索引,会比使用'博客堂','成员',MVP'几个词作索引生成的索引大很多,这样不仅浪费空间,也影响索引的效率和准确度。假如英文是按照字母而不是单词作索引,估计世界上如今就没有全文索引,也没有google了。
但是中文在分词上,相比英文有天然的屏障,英文的单词之间有间隔,但是中文不是,必须使用计算机的人工智能把句子分成一个个的词,有些时候,根据句子本身还不够,还必须根据上下文,或者一些日常知识才能判断。比如 乒乓球拍/卖/完了 和 乒乓球/拍卖/完了 ,电脑咋能知道是哪个意思并正确分词呢!
根据使用的结果,SQL Search对中文使用的应该是按字分词(可能是因为原来是英文引擎的缘故),比方说你要查'马克',它会把'马克思'也给你倒腾出来。
我的一个123M的数据库,全文索引有55M,每次全文查询都比较慢(当然机器也很次)。
--------------------------------------------------------------------------------------------------
关于按字分词:
应该还是怡红公子的说法比较妥当,大家看看这个句子:
操作系统能否用汇骗语言改写限制它对每个端口的使用率
为了验证分词,故意使用错误的分词,假如都可以索引出该句子,就说明是按字分词的。比如使用 '用汇' ?查询,也可以查出句子,所以得出了SQLServer按字分词的结论,我没有进一步检查,但是现在发现使用'写限',使用'统能'就无法查出来了,证明SQLServer中还是有简单分词的,只是分词结果不理想。
此外,SQLServer还可以使用第三方的产品增强分词的能力。
--------------------------------------------------------------------------------------------------
假如对分词有兴趣的朋友,这里有一些代码可以看,使用发现分词正确率还是很高的,不过要注册才可以得到:http://www.nlp.org.cn/project/project.php?proj_id=6