数据库的表Cnstring字段建立了全文索引
我不知道可不可以一个字段可以直接显示匹配次数。比如 CONTAINS(Cnstring,  '"计算机" or "系统" or “是" or "新东西"')有一条记录他的Cnstring字段值是“我的电脑用的是计算机系统” 实际包含了 "计算机",“系统”,“是”,那么这条记录的匹配次数是3,另外一条记录cnstring字段是“我们都在用计算机系统”这个实际匹配的是2.有没有什么方法可以快速的得到这个结果,我测试了分成多个sql执行多次查询然后在程序里计算次数或者union all语句执行速度太慢了。

解决方案 »

  1.   


    那就是分词的问题了吧
    这个我也不是太懂SELECT special_term,display_term FROM sys.dm_fts_parser('苍井空和小泽玛利亚是深受人民群众喜爱的著名艺术家',1028,0,0) special_term     display_term
    ---------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Exact Match      苍
    Exact Match      井
    Exact Match      空
    Exact Match      和
    Noise Word       小
    Exact Match      泽
    Exact Match      玛
    Exact Match      利
    Exact Match      亚
    Noise Word       是
    Exact Match      深受
    Exact Match      人民
    Exact Match      群
    Exact Match      众
    Exact Match      喜
    Exact Match      爱
    Noise Word       的
    Exact Match      著名
    Exact Match      艺
    Exact Match      术
    Exact Match      家(21 行受影响)
      

  2.   


    select Cnstring,
           case when charindex('计算机',Cnstring,1)>0 then 1 else 0 end
          +case when charindex('系统',Cnstring,1)>0 then 1 else 0 end
          +case when charindex('是',Cnstring,1)>0 then 1 else 0 end
          +case when charindex('新东西',Cnstring,1)>0 then 1 else 0 end '匹配次数'
    from [表名]
    where contains(Cnstring,'"计算机" or "系统" or "是" or "新东西"')
      

  3.   

    或者把搜索关键词写为一个表,然后关联查询计算匹配次数.create table searchword
    (word varchar(10))insert into searchword
     select '计算机' union all
     select '系统' union all
     select '是' union all
     select '新东西'
    select a.Cnstring,c.匹配次数 from
    (select Cnstring
     from [表名]
     where contains(Cnstring,'"计算机" or "系统" or "是" or "新东西"')) a
    cross apply
    (select count(1) '匹配次数' 
     from searchword b 
     where charindex(b.word,a.Cnstring,1)>0) c
      

  4.   

    你比较下面两个查询语句用时相差多少?然后做选择用哪种?select Cnstring
    from [表名]
    where contains(Cnstring,'"计算机" or "系统" or "是" or "新东西"')
    select Cnstring
    from [表名]
    where charindex('计算机',Cnstring)>0 or charindex('系统',Cnstring)>0 
    or charindex('是',Cnstring)>0 or charindex('新东西',Cnstring)>0
      

  5.   

    可能需要考虑把表的存储数据分开,否则or的效率不高,charindex也是扫描
      

  6.   

    case when charindex('系统',Cnstring,1)>0 then 1 else 0 end 刚才测试了使用这种方法 在我需要搜索的字符串不长的时候性能没有多大变化,当我的字符串很长的时候,比如分词出来有50个词,那么这个case when就50个 那么要执行charindex50次,这个速度测试出来很慢,而contains(Cnstring,'"计算机" or "系统" or "是" or "新东西"')这种索引好像OR的数量对性能的影响不是很大,我觉得这个or的数量好像不会影响扫描几次,不知道是不是算法是一次扫面的时候多次匹配 所以性能影响不大。其实我是想根据这个包含个数来排序,使得最有可能是我需要的结果排在结果的最前面,然后在程序里面依次取出,通过比较 如果是我需要的就停止后边记录的比较。使得整体的性能最快。在程序做比较的那个部分也是比较花时间的。
    我还是用的mysql和sqlite的全文索引和索引 感觉性能都不如sqlserver,而sqlserver是需要收费的。一个表数据量大概有20w条。如果确实不行我准备学习一下索引,学习算法和数据结构,不知道我专门做一个针对我这种针对匹配次数排序的索引会不会有性能上的提升?之前看过Lucene.net,这个是开源的,或者说在这个的基础上修改,不知道性能如何?