我遇到过,一很简单的select语句,
top 29或更少就只用1秒不到
top 30或更多就至少要8秒
我不知道什么原因,,哎

解决方案 »

  1.   

    1.使用复合索引ItemNo+OrgCode,那么就会在复合索引的叶级取前N个,然后使用书签也就是BookMark LookUp来查找响应的行.这样很明显会提高查找的效率,而且不用全表扫描,然后排序了.2.而单独使用ItemNo做索引,在执行计划的时候尽管也使用ItemNo单索引和书签查找,但是查找的结果还要根据OrgCode进行排序,所以效率上没有复合索引高.如果Top行数多了,那么代价就应该成几何级数增长了.
      

  2.   

    回mschen(Co-ok):
    应当跟Book Lookup没有关系
    1. 执行计划是:先对表执行Clustered Index Scan,再执行Sort/TopN Sort操作,返回结果记录,没有Book Lookup操作
    2. 用一个测试来验证:我把ItemNo的Non-Clustered Index改成Clustered Index之后,执行效果跟上面完全一样,没有变化。修改了Clustered Index之后的执行计划也和原来一样,只是Clustered Index Scan所扫描的索引变了。另外,如果把ItemNo的Non-Clustered Index修改为ItemNo+OrgCode,因为语句的select字段里面只有ItemNo+OrgCode,对这个查询使用的是covering index,所以,只需要扫描索引结构就可以取到结果,不需要book lookup,不需要额外对结果排序,这样不管是top 1000、top 2000等,都在200毫秒内就完成了。
    个人把原因定在:
    1. Clustered Index Scan操作耗费时间。但top 600、top 1000之间有什么区别,导致耗用时间差别这么大?
    2. 上面讲的grant scheduler方面。如果是这个原因,那就意味着Clustered Index Scan找到top ?条记录,以及Sort操作执行会相当快,但是因为在执行队列中的优先级低,以及SQL Server对top 600和top 1000在内存分配方式的不同,而导致时间开销的突增。希望有高手能比较详细的分析一下?
      

  3.   

    回achongsky(灵魂)
    为什么?我后面的验证应该是有道理的啊,问题出在了什么地方?