SELECT TOP 50 id, title FROM table WHERE forumid = 1 AND istop = 0 ORDER BY lastupdate DESC
--这一句可以用上复合索引1的forumid+istop组合,效率最高
SELECT TOP 50 id, title FROM table WHERE forumid = 1 AND istop < 2 ORDER BY lastupdate DESC
--这一句只能利用上复合索引1的forumid,效率较第一个就偏低
在lastupdate上建个聚集索引试试如何

解决方案 »

  1.   

    问题:lastupdate更新比较频繁,由于一旦有回帖,lastupdate就要更新一次,建立聚集索引就……
      

  2.   

    在复合索引中,列的排列顺序是非常重要的,因此要认真排列列的顺序,原则上,应该首先定义最唯一的列,例如在(COL1,COL2)上的索引与在(COL2,COL1)上的索引是不相同的,因为两个索引的列的顺序不同;为了使查询优化器使用复合索引,查询语句中的WHERE子句必须参考复合索引中第一个列
      

  3.   

    问题:lastupdate更新比较频繁,由于一旦有回帖,lastupdate就要更新一次,建立聚集索引就……
    --频繁更新的列不能建聚集索引下面的表总结了何时使用聚集索引或非聚集索引(很重要):动作描述             使用聚集索引   使用非聚集索引 
    列经常被分组排序     应             应 
    返回某范围内的数据   应             不应 
    一个或极少不同值     不应           不应 
    小数目的不同值       应             不应 
    大数目的不同值       不应           应 
    频繁更新的列         不应           应 
    外键列               应             应 
    主键列               应             应 
    频繁修改索引列       不应           应 可以通过例子来理解上表。如:返回某范围内的数据一项。比如您的某个表有一个时间列,恰好您把聚合索引建立在了该列,这时您查询2004年1月1日至2004年10月1日之间的全部数据时,这个速度就将是很快的,因为您的这本字典正文是按日期进行排序的,聚类索引只需要找到要检索的所有数据中的开头和结尾数据即可;而不像非聚集索引,必须先查到目录中查到每一项数据对应的页码,然后再根据页码查到具体内容。
      

  4.   

    你给的两个执行计划描述看,Clustered Index的位置不一样了,后一个语句执行时Clustered Index应该是在复合索引1:forumid+istop+lastupdate上。要使SELECT TOP 50 id, title FROM table WHERE forumid = 1 AND istop < 2 ORDER BY lastupdate DESC的速度最快,把Clustered Index建在复合索引1:forumid+istop+lastupdate上,字段lastupdate的排序设成desc
      

  5.   

    to gc_ding(E.T)
    复合索引1原来的顺序是forumid+istop+lastupdate,我按照最唯一的顺序改成了lastupdate+forumid+istop,两种查询语句的查询计划都相同,如下:
    查询成本:50%
    SELECT:0%,Book Lookup:40%,IndexScan:60%
    对比修改前,istop < 2的成本下降,但istop = 0的成本却上升了很多另外关于聚集索引的建立,我认为还是应该看情况,对于BBS来说,虽然把lastupdate设为聚集索引对排序和分页会比非聚集索引时快,但lastupate字段是根据帖子的回复时间来更新的,它是“大数目的不同值”和“频繁更新的列”。另外,msdn也提到:
    聚集索引不适用于具有下列属性的列:频繁更改的列
    这将导致整行移动,因为数据库引擎 必须按物理顺序保留行中的数据值。这一点要特别注意,因为在大容量事务处理系统中数据通常是可变的。宽键
    宽键是若干列或若干大型列的组合。所有非聚集索引将聚集索引中的键值用作查找键。为同一表定义的任何非聚集索引都将增大许多,这是因为非聚集索引项包含聚集键,同时也包含为此非聚集索引定义的键列。
    不知gc_ding和RicCC如何看?
      

  6.   

    每次回帖lastupdate就更改的话那forumid+istop+lastupdate上就别设成聚集索引
    但是索引的位置,不要把lastupdate放在第一位
    1. lastupdate放在第一位你上面的语句索引是失效的
    2. lastupdate放在第一位,在更新时索引数据调整量太大,要从页节点开始调整索引forumid+istop+lastupdate,lastupdate用desc排序,你上面的语句执行效率应当是很高的
      

  7.   

    title字段多大?如果不是很大,试试:forumid+istop+lastupdate+title
      

  8.   

    可惜你用的是sql2000。如果是sql2005,把title放在附加字段里,效率会大幅增长。