标题   全文索引image列,全攻略!     pengdali [原作]  
关键字   全文索引 image 
出处    
 
 今天“百年不遇”的停电了,看了一天书。晚上搞了一下全文索引,决定把心得贴出来,我尽量写的详细,大家共同学习,欢迎指正!1、启动 Microsoft Search 服务
   开始菜单-->SQL程序组-->服务管理器-->下拉筐-->Microsoft Search 服务-->启动它2、
  ..\Microsoft SQL Server\MSSQL\FTDATA\SQLServer\Config\目录里建一个非空noise.chs文件
  非空noise.chs文件,也有人说是空的noise.chs文件,但我每次都往里写几个没用的字母。3、建立环境
   打开查询分析器-->执行下列脚本:
--------------------------------------------
create database test ---创建test数据库
use test             ---选择test数据库
create table  dali (ID int not null primary key,MyImage image,FileType varchar(255),FileNmae varchar(255)) ---创建dali表
--dali表中 Id,MyImage,FileType 三列是必须的,因为要对image列索引的话,必须要有一个主键列,一个image列,一个存放文件类型的列
--我们知道在windows系统中文件类型是靠扩展名来区分的所以FileType列也就是用来放 文件的扩展名
--------------------------------------------sp_fulltext_database 'enable' --为全文索引启用数据库
sp_fulltext_catalog 'My_FullDir', 'create'  ---创建一个叫My_FullDif的全文目录declare @Key sysname ; select @Key=c.name from syscolumns a,sysconstraints b,sysobjects c where a.id=object_id('dali') and a.name='ID' and a.id=b.id and b.constid=c.id and c.name like 'PK%'
exec sp_fulltext_table 'dali','create','My_FullDir',@Key  ----这两句是为全文索引,对表进行标记sp_fulltext_column 'dali','MyImage','add',0x0804,'FileType'  ---这句是指定MyImage列为全文索引列,FileType是类型列
------------------------------------------------
4、在c盘下放一个扩展名为doc的word文件,一个扩展名为xls的excel文件,一个扩展名为htm的网页文件,个扩展名为bmp的图片
   共4个,大家可根据实际情况放入!5、插入数据
  建立下面这个存储过程
--------------------------------------------------
CREATE PROCEDURE sp_textcopy 
  @srvname    varchar (30), 
  @login      varchar (30), 
  @password    varchar (30), 
  @dbname      varchar (30), 
  @tbname      varchar (30), 
  @colname    varchar (30), 
  @filename    varchar (30), 
  @whereclause varchar (40), 
  @direction  char(1) 
AS 
/* 这是使用textcopy工具将文件插入到数据库中,如果有前台工具可以用前台开发工具将文件插入,这里为了演示 */
DECLARE @exec_str varchar (255) 
SELECT @exec_str='textcopy /S '+@srvname+' /U '+@login+' /P '+@password+' /D '+@dbname+' /T'+@tbname+' /C '+@colname+' /W"'+@whereclause+'" /F"'+@filename+'" /'+@direction
EXEC master..xp_cmdshell @exec_str
----------------------------------------------------insert dali values(1,0x,'doc','大力的doc') ---其中第二列是 0x 它是一个16进制数对应image列,是必须的,不要写null,第三列是文件类型,既扩展名sp_textcopy '你的服务器名','sa','你的密码','test','dali','MyImage','c:\大力的doc.doc','where ID=1','I'
-------依次参数是:实例名,用户名,密码,数据库名,表名,image列名,路径及文件名,条件(你必须保证它只选择一行),I
---------------------------------------------------------------------------------------------------------------------
insert dali values(2,0x,'bmp','图片')
sp_textcopy '你的服务器名','sa','你的密码','test','dali','MyImage','c:\图片.bmp','where ID=2','I' --注意条件是 ID=2insert dali values(3,0x,'xls','Excel文件')
sp_textcopy '你的服务器名','sa','你的密码','test','dali','MyImage','c:\Excel文件.xls','where ID=3','I' --注意条件是 ID=3insert dali values(4,0x,'htm','网页')
sp_textcopy '你的服务器名','sa','你的密码','test','dali','MyImage','c:\网页.htm','where ID=4','I' --注意条件是 ID=4----------上面的语句,要保证类型一样,路径正确,条件唯一正确应该就可以了6、填充全文索引sp_fulltext_table 'dali','start_full' ---第一个参数是表名,第二个参数是启动表的全文索引的完全填充7、可以开始你的实验了select * from dali where contains(MyImage,'J老师')select * from dali where contains(MyImage,'海老师')------END----------
--调试环境:SQLServer2000企业版、Windows2000高级服务器 

解决方案 »

  1.   

    正在研究中,不过还是不清楚    用contains  或者 freetext 怎么达到 象 
    like ‘%关键字%’的效果,顺便在这里问下。
      

  2.   

    执行语句
    SELECT @exec_str='textcopy /S '+@srvname+' /U '+@login+' /P '+@password+' /D '+@dbname+' /T'+@tbname+' /C '+@colname+' /W"'+@whereclause+'" /F"'+@filename+'" /'+@direction出现提示:必须声明变量 '@srvname'
      

  3.   

    中文完全可以达到,比如 like ‘%关键字%’可以实现,但是如果是英文的话,就不能完全达到了比如查询 'i am a Steve' 中的 'te'
      

  4.   

    困惑中...!困惑什么?
    对于full-text,有时候用的很爽,但是系统对词的解释有点没有规律,让我有时候很头疼,故我也不大爱用~
    附上我写的文章的一段:
    如何实现全文检索:Contains
    最后附上如何设置Full-Text,
    A.首前先谈谈如何使用:
    简单形式:
    建立测试表,数据:
    CREATE TABLE [dbo].[a] (
    [a_nam] [varchar] (20) COLLATE Chinese_Taiwan_Stroke_CI_AS NOT NULL ,
    [a_add] [varchar] (20) COLLATE Chinese_Taiwan_Stroke_CI_AS NOT NULL ,
    [a_phone] [varchar] (20) COLLATE Chinese_Taiwan_Stroke_CI_AS NULL 
    ) ON [PRIMARY]
    GO
    insert into a select 'a','beijing 北京 bb','bb'
    union select 'b','bei','bb'
    --full-text栏位为a_add
    1.单字
    I.英文单字
    Select * from a where contains(a_add,'bei')
    /*
    a_nam                a_add                a_phone              
    -------------------- -------------------- -------------------- 
    aa                   bei                  bb(1 row(s) affected)
    */
    select * from a where contains (a_add,'北京')
    /*
    a_nam                a_add                a_phone              
    -------------------- -------------------- -------------------- 
    a                    beijing 北京 bb        aa(1 row(s) affected)
    */
    2.句子必须加上“”把里面的句子括起来,例如:
    select * from a where contains (a_add,'"beijing北京"')
    否则出错
    select * from a where contains (a_add,'beijing北京 bb')
    --Syntax error occurred near 'bb'. Expected ''''' in search condition --'beijing北京 bb'.
    除非里面没有空格
    select * from a where contains (a_add,'beijing北京bb')3.条件判断,加上And、Or,记住每个单词必须用“”引起来
    Select * from a where contains(a_add,'"beijing" or "bei"')
    4.英文首字加上万用字元
    select * from a where contains (a_add,'"bei*"')
    select * from a where contains (a_add,'"北*"')B.异常的处理
    Execution of a full-text operation failed. A clause of the query contained only ignored words. 
    中文版为:Contains里只包含忽略字
    1.可能因为中文问题
     那么请选中表格,然后右键,选中Full-Text Index Table全文索引表,Edit Full-Text Indexing...编辑全文索引,对full-text栏位的Language For Word Breaker从英文改为中文,最后记住启动完全填充,防止停止没有执行.2.可能是你搜索的词被sqlserver认为是通用的词
    \mssql7\ftdata\sqlserver\config\
    下建一上 noise.chs的把里面你的词杀掉,然后停止microsoft Seacher服务,再重新启动该服务,查询时用where contains(fieldNam,'"*你要查的词*"')即可,双引号与*号可以有,也可以无,看你用那种方式.3.如果没有办法得到结果,又没有错误,那么请到Database->Full-text Catalogs->右键菜单->Strat Full Population,设置ok!或者右击表格,Strat Full Population,然后再执行sql
      

  5.   

    标题   索引在数据库中的应用分析     选择自 hellenlong 的 Blog  
    关键字   索引在数据库中的应用分析 
    出处    
     
     索引是提高数据查询最有效的方法,也是最难全面掌握的技术,因为正确的索引可能使效率提高10000倍,而无效的索
     
    引可能是浪费了数据库空间,甚至大大降低查询性能。 
     索引的管理成本
     
    1、  存储索引的磁盘空间
     
    2、  执行数据修改操作(INSERT、UPDATE、DELETE)产生的索引维护
     
    3、  在数据处理时回需额外的回退空间。
     
    实际数据修改测试:
     
    一个表有字段A、B、C,同时进行插入10000行记录测试
     
    在没有建索引时平均完成时间是2.9秒
     
    在对A字段建索引后平均完成时间是6.7秒
     
    在对A字段和B字段建索引后平均完成时间是10.3秒
     
    在对A字段、B字段和C字段都建索引后平均完成时间是11.7秒
     
    从以上测试结果可以明显看出索引对数据修改产生的影响
     
    索引按存储方法分类
     
    B*树索引
     
    B*树索引是最常用的索引,其存储结构类似书的索引结构,有分支和叶两种类型的存储数据块,分支块相当于书的大目
     
    录,叶块相当于索引到的具体的书页。一般索引及唯一约束索引都使用B*树索引。
     
    位图索引
     
    位图索引储存主要用来节省空间,减少ORACLE对数据块的访问,它采用位图偏移方式来与表的行ID号对应,采用位图索
     
    引一般是重复值太多的表字段。位图索引在实际密集型OLTP(数据事务处理)中用得比较少,因为OLTP会对表进行大量
     
    的删除、修改、新建操作,ORACLE每次进行操作都会对要操作的数据块加锁,所以多人操作很容易产生数据块锁等待甚
     
    至死锁现象。在OLAP(数据分析处理)中应用位图有优势,因为OLAP中大部分是对数据库的查询操作,而且一般采用数
     
    据仓库技术,所以大量数据采用位图索引节省空间比较明显。
     
    索引按功能分类
     
    唯一索引
     
    唯一索引有两个作用,一个是数据约束,一个是数据索引,其中数据约束主要用来保证数据的完整性,唯一索引产生的
     
    索引记录中每一条记录都对应一个唯一的ROWID。
     
    主关键字索引
     
    主关键字索引产生的索引同唯一索引,只不过它是在数据库建立主关键字时系统自动建立的。
     
    一般索引
     
    一般索引不产生数据约束作用,其功能主要是对字段建立索引表,以提高数据查询速度。
     索引按索引对象分类
     
    单列索引(表单个字段的索引)
     
    多列索引(表多个字段的索引)
     
    函数索引(对字段进行函数运算的索引)
     
    建立函数索引的方法:
     
    create index 收费日期索引 on GC_DFSS(trunc(sk_rq))
     
    create index 完全客户编号索引 on yhzl(qc_bh||kh_bh)
     
    在对函数进行了索引后,如果当前会话要引用应设置当前会话的query_rewrite_enabled为TRUE。
     
    alter session set query_rewrite_enabled=true
     
    注:如果对用户函数进行索引的话,那用户函数应加上 deterministic参数,意思是函数在输入值固定的情况下返回值
     
    也固定。例:
    create or replace function trunc_add(input_date date)return date deterministic
     
    as 
    begin
        return trunc(input_date+1);
     
    end trunc_add;
     
    应用索引的扫描分类
     
    INDEX UNIQUE SCAN(按索引唯一值扫描)
     
    select * from zl_yhjbqk where hbs_bh='5420016000'
     
    INDEX RANGE SCAN(按索引值范围扫描)
     
    select * from zl_yhjbqk where hbs_bh>'5420016000'
     
    select * from zl_yhjbqk where qc_bh>'7001'
     
    INDEX FAST FULL SCAN(按索引值快速全部扫描)
     
    select hbs_bh from zl_yhjbqk order by hbs_bh
     
    select count(*) from zl_yhjbqk
     
    select qc_bh from zl_yhjbqk group by qc_bh
     
    什么情况下应该建立索引
     
    表的主关键字
     
    自动建立唯一索引
     
    如zl_yhjbqk(用户基本情况)中的hbs_bh(户标识编号)
     
    表的字段唯一约束
     
    ORACLE利用索引来保证数据的完整性
     
    如lc_hj(流程环节)中的lc_bh+hj_sx(流程编号+环节顺序)
     
    直接条件查询的字段
     
    在SQL中用于条件约束的字段
     
    如zl_yhjbqk(用户基本情况)中的qc_bh(区册编号)
     
    select * from zl_yhjbqk where qc_bh=’7001’
     
    查询中与其它表关联的字段
     
    字段常常建立了外键关系
     
    如zl_ydcf(用电成份)中的jldb_bh(计量点表编号)
     
    select * from zl_ydcf a,zl_yhdb b where a.jldb_bh=b.jldb_bh and b.jldb_bh=’540100214511’
     查询中排序的字段
     
    排序的字段如果通过索引去访问那将大大提高排序速度
     
    select * from zl_yhjbqk order by qc_bh(建立qc_bh索引)
     
    select * from zl_yhjbqk where qc_bh='7001' order by cb_sx(建立qc_bh+cb_sx索引,注:只是一个索引,其中包
     
    括qc_bh和cb_sx字段)
     
    查询中统计或分组统计的字段
     
    select max(hbs_bh) from zl_yhjbqk
     
    select qc_bh,count(*) from zl_yhjbqk group by qc_bh
     
    什么情况下应不建或少建索引
     
    表记录太少
     
    如果一个表只有5条记录,采用索引去访问记录的话,那首先需访问索引表,再通过索引表访问数据表,一般索引表与数
     
    据表不在同一个数据块,这种情况下ORACLE至少要往返读取数据块两次。而不用索引的情况下ORACLE会将所有的数据一
     
    次读出,处理速度显然会比用索引快。
     
    如表zl_sybm(使用部门)一般只有几条记录,除了主关键字外对任何一个字段建索引都不会产生性能优化,实际上如果
     
    对这个表进行了统计分析后ORACLE也不会用你建的索引,而是自动执行全表访问。如:
     
    select * from zl_sybm where sydw_bh='5401'(对sydw_bh建立索引不会产生性能优化)
     
     
     经常插入、删除、修改的表
     
    对一些经常处理的业务表应在查询允许的情况下尽量减少索引,如zl_yhbm,gc_dfss,gc_dfys,gc_fpdy等业务表。
     
    数据重复且分布平均的表字段
     
    假如一个表有10万行记录,有一个字段A只有T和F两种值,且每个值的分布概率大约为50%,那么对这种表A字段建索引一
     
    般不会提高数据库的查询速度。
     
    经常和主字段一块查询但主字段索引值比较多的表字段
     
    如gc_dfss(电费实收)表经常按收费序号、户标识编号、抄表日期、电费发生年月、操作标志来具体查询某一笔收款的
     
    情况,如果将所有的字段都建在一个索引里那将会增加数据的修改、插入、删除时间,从实际上分析一笔收款如果按收
     
    费序号索引就已经将记录减少到只有几条,如果再按后面的几个字段索引查询将对性能不产生太大的影响。
     
    如何只通过索引返回结果
     
    一个索引一般包括单个或多个字段,如果能不访问表直接应用索引就返回结果那将大大提高数据库查询的性能。对比以
     
    下三个SQL,其中对表zl_yhjbqk的hbs_bh和qc_bh字段建立了索引:
     
    1 select hbs_bh,qc_bh,xh_bz from zl_yhjbqk where qc_bh=’7001’
     
    执行路径:
     
    SELECT STATEMENT, GOAL = CHOOSE         11  265 5565
     
     TABLE ACCESS BY INDEX ROWID    DLYX    ZL_YHJBQK   11  265 5565
     
     INDEX RANGE SCAN  DLYX    区册索引    1   265 
     平均执行时间(0.078秒)
     
    2 select hbs_bh,qc_bh from zl_yhjbqk where qc_bh=’7001’
     
    执行路径:
     
    SELECT STATEMENT, GOAL = CHOOSE         11  265 3710
     
     TABLE ACCESS BY INDEX ROWID    DLYX    ZL_YHJBQK   11  265 3710
     
      INDEX RANGE SCAN  DLYX    区册索引    1   265 
     
    平均执行时间(0.078秒)
     
    3 select qc_bh from zl_yhjbqk where qc_bh=’7001’
     
    执行路径:
     
    SELECT STATEMENT, GOAL = CHOOSE         1   265 1060
     
     INDEX RANGE SCAN   DLYX    区册索引    1   265 1060
     平均执行时间(0.062秒)
     从执行结果可以看出第三条SQL的效率最高。执行路径可以看出第1、2条SQL都多执行了TABLE ACCESS BY INDEX ROWID(
     
    通过ROWID访问表) 这个步骤,因为返回的结果列中包括当前使用索引(qc_bh)中未索引的列(hbs_bh,xh_bz),而第3
     
    条SQL直接通过QC_BH返回了结果,这就是通过索引直接返回结果的方法。
     如何重建索引
     
    alter index 表电量结果表主键 rebuild
     如何快速新建大数据量表的索引
     
    如果一个表的记录达到100万以上的话,要对其中一个字段建索引可能要花很长的时间,甚至导致服务器数据库死机,因
     
    为在建索引的时候ORACLE要将索引字段所有的内容取出并进行全面排序,数据量大的话可能导致服务器排序内存不足而
     
    引用磁盘交换空间进行,这将严重影响服务器数据库的工作。解决方法是增大数据库启动初始化中的排序内存参数,如
     
    果要进行大量的索引修改可以设置10M以上的排序内存(ORACLE缺省大小为64K),在索引建立完成后应将参数修改回来
     
    ,因为在实际OLTP数据库应用中一般不会用到这么大的排序内存。