本帖最后由 Lansie 于 2013-03-05 11:24:24 编辑

解决方案 »

  1.   

    --try
    create index idx_t_A_B_C on t(a,b,c) inclue(d)
      

  2.   

    原因是index2没有包含字段d,你的结果需要字段d,优化器认为不如直接scan index1
    如果2005+,如楼上修改index2增加包含列即可
      

  3.   

    谢谢各位的答复。
    单单这个案例的解决办法是比较简单,但实际情况需要的字段很多,如果都include的话,这个索引会很大而且影响表的其它操作。
    而且我想知道sql引擎是如何考虑的,从结果来看,index1 scan的效率远远低于index2 seek,即便多了一个字段D,也应该index2 seek后再去主表取字段D
      

  4.   

    看下第一个查询的执行计划,应该除了index2 seek外,还有一个index1的键查找过程第二个查询如何选择主要看A1的值处在所有A的值得位置,如果A<A1的数量足够小,应该会选择index2 seek+index1 seek,否则会选择index1 scan
      

  5.   


    第一个查询是index2 seek+key lookup
    第二个查询的结构是160条记录,远远小于总共400w的记录数,但执行计划还是index1的scan,不知是什么原因
      

  6.   

    1、key lookup大部分情况下是某些列没有索引,要把select和where中出现的列用include包住。
    2、那是因为优化器觉得找不到比scan更好的方式,所以没有“用”索引。也证明索引没用上或者缺失了索引。
      

  7.   

    因为你的INDEX 2
    你看看你的执行计划SQL Server 预估返回的行数是不是跟真实行数有偏差。可能是因为统计信息问题。 
      

  8.   

    更新一下索引统计信息 
    清楚一下执行计划缓存
    然后再看看,如果不行就强制他使用index2