最近在看查询计划方面的书,当看了RID lookup运算符在实践时,遇到不解!按照原理上说,当在堆上的时候,建立非聚集索引,非聚集索引的叶子层应该有book指向RID,如果查询中包含非聚集索引谓词且查询关键字中有非覆盖的列,那么SQL Server就有可能使用RID lookup运算符我试图造一个查询让SQL Server使用RID lookup运算符,却没有成功,如下:
[code=SQL]
[/if object_id('test1') is not null
drop table test1
gocreate table test1(id int, a int, b int, c int)
gocreate nonclustered index IX_a on test1(a)select a, b
from test1
where a > 9854
]似乎SQL Server认为使用RID bookup的开销太大,而使用表扫描的进行查询;
希望了解的朋友指点一下,是不是我查询本身存在问题,或者能帮我造一个使用RID bookup的查询,谢谢

解决方案 »

  1.   


    已经看了查询计划了,我造的这个查询没有使用带RID bookup,而使用的是表扫描!
      

  2.   

    查询优化器会自动选择合适的扫描方式来做如果查询中包含非聚集索引谓词且查询关键字中有非覆盖的列,那么SQL Server就有可能使用RID lookup运算符这个都是看具体情况 ,使用CPU开销这些的
      

  3.   


    其实我就是想找一个使用RID lookup 的列子
      

  4.   

    lz多大数据量,数据量太小直接tablescan 估计就o了,搞个1000000万数据量试试.
    查询优化器并不找最优的,要是小数据量都不值当分析直接tablescan了.
      

  5.   

    还是不行啊,我试过了,插入了1000000条数据后,查询计划还是表扫描if object_id('test1') is not null
    drop table test1
    gocreate table test1(id int, a int, b int, c int)
    gocreate nonclustered index IX_a on test1(a)declare @i int
    declare @a int
    declare @c int
    set @i = 1000
    Set @a = 1000
    set @c =100
    while (@i < 1000000)
    begin
    insert into test1
    values (@i, @a, 2, @c)
    set @i = @i + 1
    set @a = @a + 1
    end
    goselect a, b
    from test1
    where a > 315474
      

  6.   

    我刚做测试了,
    当select a, b
    from test1
    where a<1000的时候选择的是rid lookup
    当a<2000时就是table scan了,应该是分析器自己抉择评估方案,当取的数据小于某个数量级时就用rid lookup,当多时就tablescan了,具体临界点如果有兴趣lz可以找找,然后告诉大家.
      

  7.   

    非常感谢这个朋友,其实刚才你没说之前,我已经开始这个测试,以100万条记录来看临界值大概在1750,但我进一步发现这个临界值与数据总量是有关系的,当数据总量为10万条时,临界值大概是150,当数据总量为1万条时,临界值大概是15从这个测试上看来,book这种随机IO是很耗资源的,在堆上估算大概1条book相当于667条表扫描,也似乎看得出来随着数据量的增加book的效率逐渐显现
      

  8.   

    另外我补充一点:如果是在聚集索引上的非聚集索引,用的Key lookup,如10万条记录时,临界点大概145
      

  9.   

    还是尽量让索引覆盖谓词,这样走index seek要比Book效率高.