有一个表,主要字段如下:
(也许会有一个名为ID的整型的唯一标识符)
NewsName nvarchar 新闻名
ClickTimes int 点击次数
InsertTime datatime 发布时间用户可以按新闻名进行查询,查询出来的数据,先按点击次数排(倒序),如果点击次数相同的,再按时间排(倒序)表中有百万级的数量,虽然建有索引,但大多数情况下的查询都是对新闻名称的模糊搜索NewsName like '%xxx%',索引一点也用不上。请教在这样情况下有什么办法可以进行优化?

解决方案 »

  1.   

    实际的数据库表中,从5月1号开始的记录已经达到八十多万。就是说每月20万的记录。我的测试表中是100万的记录。另外,数据库服务器与IIS服务器在一台机器上。
      

  2.   

    like 还是不要用了。数据量大的话是没有办法的。如果在数据库里做,就用全文检索吧。虽然检索结果未必很满意,但是效率可以保障。也可以自己做个倒排索引(得有词库),那么效果会更好。
      

  3.   

    IIS服务器跟数据库服务器在一台机器上,这种情况下怎么能跟淘宝比呢。
      

  4.   

    1\like '%xxx%' 在2005里是可以用到索引的
    2\建立全文索引看看
      

  5.   

    TO => TigerEatAngil(老虎吃肉,天使减肥) :谢谢你的建议
    1. 使用的是2000
    2. 全文索引的查询结果听说不如人意呢.
      

  6.   

    听说oracle性能不错,有没有想换个数据库试试.纯属个人瞎想
      

  7.   

    oracle是需要钱滴。
    自己开发时可以用用盗版什么的,难道数据库服务器上也用盗版?使用oracle的话,是否操作系统使用linux更合适?这样以来技术人员也要相应调整,成本太高了。其实现在只想用成本最低的方案解决现在经常出现的死锁现象。
      

  8.   

    对于海量数据的模糊搜索,对什么数据库都是难题,oracle碰上这事照样没招
    我目前对这种烂事的办法是:
    相关排序索引建好后,前台用户采用分页显示,数据库采用分页查询,就是说假如设定一页10条,当前台用户看第一页时,数据库只查询top 10条给前台,当用户看第二页时,
    数据库只查top 20并只把最后10条给前台,这样基本可以保证前几页的查询速度
      

  9.   

    StandALoneComplex(shinji)的建议对于海量数据的量分比较有帮助,只分页不做模糊搜索时,分页速度还是比较快的。但一到模糊搜索那儿就不行了,看来得另想办法。比方说全文检索之类的。
    不过目前的数据库是不能这么处理了,因为会伤筋动骨的
      

  10.   

    那是因为你把分页和模糊搜索放在一起了,把它们分开,先搜索出来再做分页,
    全文索引我也试过,速度很不令人满意,最后只能放弃,我这种方式实际上是通过top N 的方式避免全表扫描,令数据库在找到前N条时,就停止查询,不过我这种方式也是有问题的,如果符合条件的记录很少,凑不够一页,或符合条件的记录都在数据堆的尾端,那也是要花大量的时间的做全表搜索的,我的感觉是,七成的搜索能在几秒之内收敛,剩下的就没准了.
      

  11.   

     回复人:StandALoneComplex(shinji) ( 一级(初级)) 信誉:100  2007-08-17 09:50:55  得分:0

    那是因为你把分页和模糊搜索放在一起了,把它们分开,先搜索出来再做分页,
    全文索引我也试过,速度很不令人满意,最后只能放弃,我这种方式实际上是通过top N 的方式避免全表扫描,令数据库在找到前N条时,就停止查询,不过我这种方式也是有问题的,如果符合条件的记录很少,凑不够一页,或符合条件的记录都在数据堆的尾端,那也是要花大量的时间的做全表搜索的,我的感觉是,七成的搜索能在几秒之内收敛,剩下的就没准了.
    ============================
    请问能不能详细说一下你的做法?
      

  12.   

    create table #temp(newsname varchar(100),clicktimes int,inserttimes datetime)
    ///
    insert into #temp
    select top n * 
    from news_info where NewsName like '%'+@serach+'%' order by clickTimes desc ,insertTimes desc  ------(clicktimes与inserttimes建好相应的复合索引)
    ///
    ---(其中///夹起来的部分需要拼成字符串然后用exec(@variable) 方式执行,因为top N不支持变量,2005就没这个问题了)
    之后你的#temp中只会有几十条数据,按预定排序规则用分页算法对这个#temp分页,把最后一页给前台
      

  13.   

    To => StandALoneComplex(shinji):
    是不是就是说把查询出的数据写入到临时表里面去。可是第一次查询时速度仍然很慢,是不是?
      

  14.   

    如果每页是10条的话,第一次查询是top 10 ,第二次查询是top 20,第一次查询最快,越往后翻越慢,
      

  15.   

    To => StandALoneComplex(shinji):
    你说是使用top N的方式避免全表扫描,可是后面的查询条件中使用了like '%XXX%',这时已经进行全表扫描了啊。
      

  16.   

    呵呵,我这里有些地方用了全文检索,有的地方用了dotLucene.
    效率可以保障。
      

  17.   

    楼上能不能详细说一下?dotLucene?是倒排索引?
      

  18.   

    假如你的表中有一千万数据,其中在第二千行的位置上有一条符合条件的数据,
    select top 1 * from tablename where name like @s

    select  * from tablename where name like @s
    效果是完全不一样的,因为第一句避免了全表扫描
      

  19.   

    晕,在数据库的全文索引其实也就是分词后的倒排索引方式。
    因为微软的中文分词很差劲,所以尽量不用SQL的全文检索。网络上现在有不少类似的搜索,lucene(java版本,dotlucene是dot net版本)就是其中之一
      

  20.   

    回复人:sp4(1) ( 五级(中级)) 信誉:100  2007-08-20 09:36:28  得分:0

    晕,在数据库的全文索引其实也就是分词后的倒排索引方式。
    因为微软的中文分词很差劲,所以尽量不用SQL的全文检索。网络上现在有不少类似的搜索,lucene(java版本,dotlucene是dot net版本)就是其中之一
    ===================================
    先谢过这位兄弟。lucene我刚知道不久,正在了解。问题是目前的网站版本是ASP的,可以直接使用吗?难道真的要使用web service啊,郁闷。
      

  21.   

    StandALoneComplex(shinji) 
    建议很好