sql全文索引
在Microsoft SQL Server 7.0 中提供了全文索引服务(Full-Text Search Service),在查询性能上,对varchar,char,text类型的字段的匹配查询比用SQL语句使用Like操作符及匹配符的速度快10倍以上;在查询匹配上,提供了模糊匹配的高级搜索性能并能够返回查询的命中率。 Full Text Search Service包含在SQL Server 7.0中,在SQL Server 7 Destop版中不起作用。安装SQL Server时,无法缺省安装它,需要在Custom Installation 中选择。 服务安装完后在SQL Server EntERPrise Manager中的Support Services中显示为Full-text Search,在控制面版中的服务中显示为Microsoft Search.可以在SQL Server EnterPrise Manager中启动这个服务,就可以在表中加入全文索引了。要注意:只有有唯一索引栏的表才能建立全文索引,并且全文索引建立好之后就不能改变表了,如要改变表就必须得取出索引,然后再装入。
对表设置全文索引应用如下步骤:
1.选择要建立全文索引的表,然后选择: Full-Text Index Table ->Define Full-Text Indexing on a table
2.系统会启动SQL Server Full-Text Index 向导。
3.选择一个唯一索引。
4.选择一个要建立索引的字段。
5.选择catalog。
6.选择更新索引计划(由于全文索引和普通索引表不同,不能自动更新,所以得加入一个计划
)。
7.Finish。
8.选择在数据库Full-text catalogs中里的新建立的catalog,然后运行Start Population,Full Population 就可以了。
㈡ 建立全文检索的sql语句
前言:微软的SQL Server数据库是一个在中低端企业应用中占有广泛市场的关系型数据库系统,它以简单、方便、易用等特性深得众多软件开发人员和数据库管理人员的钟爱。但SQL Server 7.0以前的数据库系统由于没有全文检索功能,致使无法提供像文本内容查找此类的服务,成为一个小小的遗憾。从SQL Server 7.0起,到如今的SQL Server 2000终于具备了全文检索功能,使用户可以高效地检索存储在数据库char、varchar、text、ntext、nchar、nvarchar等数据类型列中的文本数据。
建立全文索引
在进行全文检索之前,必须先建立和填充数据库全文索引。为了支持全文索引操作,SQL Server 7.0新增了一些存储过程和Transact-SQL语句。使用这些存储过程创建全文索引的具体步骤如下(括号内为调用的存储过程名称):
1. 启动数据库的全文处理功能(sp_fulltext_
database);;
2. 建立全文检索目录(sp_fulltext_catalog);
3.在全文检索目录中注册需要全文索引的表(sp_fulltext_table);
4. 指出表中需要全文检索的列名(sp_fulltext_
column);;
5. 为表创建全文索引(sp_fulltext_table);;
6. 填充全文检索目录(sp_fulltext_catalog)。
下面举例说明如何创建全文索引,在本例中,对Test数据库Book表中Title列和Notes列建立全文索引。
use test //打开数据库
//打开全文索引支持,启动SQL Server的全文搜索服务
execute sp_fulltext_database ‘enable’
//建立全文检索目录ft_test
execute sp_fulltext_catalog ‘ft_test’, ‘create’
为Title列建立全文索引数据元,pk_title为Book表中由主键所建立的唯一索引,这个参数是必需的。
execute sp_fulltext_table ‘book’,‘create’, ‘ft_test’,‘pk_title’
//设置全文索引列名
execute sp_fulltext_column ‘book’, ‘title’, ‘add’
execute sp_fulltext_column ‘book’,‘notes’, ‘add’
//建立全文索引
execute sp_fulltext_table ‘book’, ‘activate’
//填充全文索引目录
execute sp_fulltext_catalog ‘ft_test’, ‘start_full’
至此,全文索引建立完毕。
进行全文检索
SQL Server 2000提供的全文检索语句主要有CONTAINS和FREETEXT。CONTAINS语句的功能是在表的所有列或指定列中搜索:一个字或短语;一个字或短语的前缀;与一个字相近的另一个字;一个字的派生字;一个重复出现的字。
CONTAINS语句的语法格式为:
CONTAINS({column | *}), <contains_search_condition> )
其中,column是搜索列,使用“*”时说明对表中所有全文索引列进行搜索。Contains_search_
condition 说明CONTAINS语句的搜索内容,其语法格式为:
{||||}[{{AND|AND NOT|OR}}] [...n]
下面就simple_term和prefix_term参数做简要说明:
simple_term是CONTAINS语句所搜索的单字或短语,当搜索的是一个短语时,必须使用双引号作为定界符。其格式为:
{‘word’|“ phrase”}
prefix_term说明CONTAINS语句所搜索的字或短语前缀,其格式为:
{“word*” | “phrase*”}
例如,下面语句检索Book表的Title列和Notes列中包含“database”或“computer”字符串的图书名称及其注释信息:
select title, notes
from book
where contains(tilte, ‘database’) or contains(notes,‘database’)
or contains(title,‘computer’) or contains(notes,‘computer’)
FREETEXT语句的功能是在一个表的所有列或指定列中搜索一个自由文本格式的字符串,并返回与该字符串匹配的数据行。所以,FREETEXT语句所执行的功能又称做自由式全文查询。
FREETEXT语句的语法格式为:FREETEXT({column | * },‘freetext_string’)
其中,column是被搜索列,使用“*”时说明对表中的所有全文索引列进行搜索。Freetext_string参数指出所搜索的自由文本格式字符串。
例如,下面语句使用FREETEXT语句搜索Book表中包含“Successful Life”字符串的数据行:
select title, notes
from book
where freetext(*,‘Successful Life’)
㈢ 如何使用SQL Server中的全文索引
一般情况,使用SQL Server中的全文索引,经过大体4个步骤:
1). 安装full text search全文索引服务;
2). 为数据表建立full text catalog全文索引目录;
3). 进行full text catalog的population操作(使全文索引与数据表内容同步);
4). 使用全文索引进行查询。
为了在数据表内容更新时全文索引数据库的内容也保持最新,可以通过第5步建立full text catalog 的Population自动操作Schele.
http://jingyan..com/article/a681b0de0cc4023b1943467a.html
㈣ 为什么说SQLServer全文索引有局限性
下面假设有这样一个例子:在DataBase_name。dbo。Table_name中有一个名为Title(标题)和Contents(内容)的字段,现在需要查询在Title或者Contents中包括“qq”字符的所有记录。 面对这样的一个场景,我们通常都会写这样一个脚本:SELECT * FROM DataBase_name。
dbo。Table_name WHERE Title LIKE '%qq%' OR Contents LIKE '%qq%'; 没错,这也是我第一个想到的方法。但是我们需要思考的是:随着时间的推移,数据会越来越大,那个时候我们该如何提高我们的性能?用户随时都有可能再添加对Remark(备注)字段进行查找,难道我们就应该不厌其烦地修改程序代码? 需要指出的是:面对这样的查询条件,即使Title和Contents上都有索引,我们也无法使用到索引,因为在 '%qq%'的“qq”前面使用了通配符,所以无法使用到索引;如果查询的条件是'qq%',那到是可以利用上索引。
在许多数据库性能调优的文章上都说OR这个谓词可以使用SELECT UNION ALL SELECT这样的方式来提高性能,但是需要提醒大家的是:如果在一条记录中字段Title和Contents都同时存在“中国”字符的话,那么返回的结果就会出现两条相同的记录,如果你希望是唯一的记录,那么这个时候你就要注意了。
现在回到我们上面的问题,大概这个时候大家都应该想到了数据库的全文索引了。全文索引是一种特殊类型的基于标记的功能性索引,由 Microsoft SQL Server 全文引擎 (MSFTESQL) 服务创建和维护。创建全文索引的过程与创建其他类型的索引的过程差别很大。
MSFTESQL 不是基于某一特定行中存储的值来构造 B 树结构,而是基于要索引的文本中的各个标记来创建倒排、堆积且压缩的索引结构。(摘自MSDN) 为什么说SQL Server 全文索引不是万能的?可能大家都怀疑我是不是标题党了,呵呵,马上就讲到,那就是这个全文索引能解决我们一开始提到的场景吗?回答是否定。
为什么呢?因为它的分词和倒排索引造成了对字符串“tqq。tencent。com”这样的内容进行‘“*qq*”’这样的条件查询,上面那条记录是不会被返回的。它的分词应该是正向最大值的分词方法,它没有对方向再进行一次分词和索引,索引无法查询到。这个可能会被大家所忽略掉的。
㈤ sql server 索引 全文索引和聚类索引的区别
http://wenku..com/view/22ee60d376a20029bd642d75.html
看看文档吧,有些东西需要耐心看下。
全文引擎使用全文索引中的信息来编译可快速搜索表中的特定词或词组的全文查询。 全文索引将有关重要的词及其位置的信息存储在数据库表的一列或多列中。 全文索引是一种特殊类型的基于标记的功能性索引,它是由 SQL Server 全文引擎生成和维护的。 生成全文索引的过程不同于生成其他类型的索引。 全文引擎并非基于特定行中存储的值来构造 B 树结构,而是基于要编制索引的文本中的各个标记来生成倒排、堆积且压缩的索引结构。全文索引大小仅受运行 SQL Server 实例的计算机的可用内存资源限制。
从 SQL Server 2008 开始,全文索引与数据库引擎集成在一起,而不是像 SQL Server 早期版本那样位于文件系统中。对于新数据库,全文目录现在为不属于任何文件组的虚拟对象;它仅是一个表示一组全文索引的逻辑概念。 然而,请注意,在升级 SQL Server 2005 数据库(即包含数据文件的任意全文目录)的过程中,将创建一个新文件组。
㈥ sql 全文搜索 怎么分词的
全文索引的核心理念是倒排索引(即反向索引),而最大的技术难点就在于分词。
英文的分词很简单,直接按空格分词即可。但中文不能这么干,主要原因有两点:
中文词与词之间没有空格
中文分词结果存在歧义。例如:周立波/小人/傻逼 和 周立/波小/人傻逼,两种分词都说得通,只有结合上下文才知道哪一种对
因此,中文分词比英文分词要困难得多,学术界在这一领域已经研究了多年,并取得了很多研究成果,但目前,中文分词的技术仍然很不完善。
回到全文搜索的话题,sql server自带的中文分词应该是基于正向最大匹配法的,说实话效果并不好。要求不高的话可以凑活用。除此之外,也有一些开源或商业的项目,例如Lucene(及其后续衍生),盘古等等,比sql server自带的要强。但这些项目也有问题:一是分词效果难称完美,二是在数据库中使用比较麻烦。
以上全部手打。有什么问题请继续问。
㈦ 关于MSSQL 全文索引 某些词特别慢的问题
1. 执行计划中明明有使用到索引,为什么执行还是这么慢?
2. 执行计划中显示扫描行数为 644,为什么 slow log 中显示 100 多万行?
a. 我们先看执行计划,选择的索引 “INDX_BIOM_ELOCK_TASK3(TASK_ID)”。结合 sql 来看,因为有 "ORDER BY TASK_ID DESC" 子句,排序通常很慢,如果使用了文件排序性能会更差,优化器选择这个索引避免了排序。
那为什么不选 possible_keys:INDX_BIOM_ELOCK_TASK 呢?原因也很简单,TASK_DATE 字段区分度太低了,走这个索引需要扫描的行数很大,而且还要进行额外的排序,优化器综合判断代价更大,所以就不选这个索引了。不过如果我们强制选择这个索引缺纯(用 force index 语法),会看到 SQL 执行速度更快少于 10s,那是因为优化器基于代价的原则并不等价于执行速度的快慢;
b. 再看执行计划中的 type:index,"index" 代表 “全索引扫描”,其实和全表扫描差不多,只是扫描的时候是按照索引次序进行而不是行,主要优点就是避免了排序,但是开销仍然非常大。
Extra:Using where 也意味着扫描完索引后还需要回表进行筛选。一般来说,郑数得保证 type 至少达到 range 级别,最好能达到 ref。
在第 2 点中提到的“慢日志记录Rows_examined: 1161559,看起来是全表扫描”,这里更正为“全索引扫描”,扫描行数确实等于表的行数;
c. 关于伏丛咐执行计划中:“rows:644”,其实这个只是估算值,并不准确,我们分析慢 SQL 时判断准确的扫描行数应该以 slow log 中的 Rows_examined 为准。
4. 优化建议:添加组合索引 IDX_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID)
优化过程:
TASK_DATE 字段存在索引,但是选择度很低,优化器不会走这个索引,建议后续可以删除这个索引:
select count(*),count(distinct TASK_DATE) from T_BIOMA_ELOCK_TASK;+------------+---------------------------+| count(*) | count(distinct TASK_DATE) |+------------+---------------------------+| 1161559 | 223 |+------------+---------------------------+
在这个 sql 中 REL_DEVID 字段从命名上看选择度较高,通过下面 sql 来检验确实如此:
select count(*),count(distinct REL_DEVID) from T_BIOMA_ELOCK_TASK;+----------+---------------------------+| count(*) | count(distinct REL_DEVID) |+----------+---------------------------+| 1161559 | 62235 |+----------+---------------------------+
由于有排序,所以得把 task_id 也加入到新建的索引中,REL_DEVID,task_id 组合选择度 100%:
select count(*),count(distinct REL_DEVID,task_id) from T_BIOMA_ELOCK_TASK;+----------+-----------------------------------+| count(*) | count(distinct REL_DEVID,task_id) |+----------+-----------------------------------+| 1161559 | 1161559 |+----------+-----------------------------------+
在测试环境添加 REL_DEVID,TASK_ID 组合索引,测试 sql 性能:alter table T_BIOMA_ELOCK_TASK add index idx_REL_DEVID_TASK_ID(REL_DEVID,TASK_ID);
添加索引后执行计划:
这里还要注意一点“隐式转换”:REL_DEVID 字段数据类型为 varchar,需要在 sql 中加引号:AND T.REL_DEVID = 000000025xxx >> AND T.REL_DEVID = '000000025xxx'
执行时间从 10s+ 降到 毫秒级别:
1 row in set (0.00 sec)
结论
一个典型的 order by 查询的优化,添加更合适的索引可以避免性能问题:执行计划使用索引并不意味着就能执行快。