书签查询

在上面的例子中,我们了解了SQL Server如何使用索引查找来有效地获取满足谓词上的数据,然而,我们也知道非聚集索引并不覆盖表的所有列.试想一下,若我们有这样一个在非聚集索引键上的谓词查询:select查询的列并未被索引覆盖,当SQL Server在非聚集索引上查找时,将会丢失一些需要的列,与之相反,如果在聚集索引或唯上执行扫描时,将获取所有列,由于要扫描表的每一行,其操作显然不是很有效.以下的查询就是如此:

SELECT [OrderId], [CustomerId] FROM [Orders] WHERE [OrderDate] = '1998-02-26'

上面的查询与先前我们进行索引查找的用到的查询一样,唯一不同的是,这里我们选择了两列:OrderIDCustomerID.非聚集索引OrderDate列仅覆盖OrderID列.

         SQL Server具有处理这一问题的方法,对于从非聚集索引中获取的每一行,它可能查询包含在聚集索引中的剩余列(这里是CustomerID),我们称该操作为"书签查询".书签查询是一个指向堆或聚集索引行的指针.SQL Server在非聚集索引中存储每一行的书签,这样一来,可以从非聚集索引直接转向基表中相对应的记录行.

下图说明了书签查询先在非聚集索引叶级上查找,然后从指向聚集索引的数据页中查找的情况。
355374_200811151427271.jpg

SQL Server 2000使用指定的迭代器来实现书签查询,通过文本计划可以看出索引查找与书签查询迭代器:

|--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([Orders]))
     |--Index Seek(OBJECT:([Orders].[OrderDate]),
        SEEK:([Orders].[OrderDate]=Convert([@1])) ORDERED FORWARD)
         下图为SQL Server 2000中的图形查询计划:
中将使用嵌套循环联接和聚集索引查找来实现,仅当基表含有聚集索引或查询(基表是堆),中的查询计划与中的计划有些不同,但逻辑上是相同的.聚集索引查找就是通过关键来实现的一种书签查询或通过属性.以下是的图形查询计划和文本查询计划:
|--Nested Loops(Inner Join, OUTER REFERENCES:([Orders].[OrderID]))
       |--Index Seek(OBJECT:([Orders].[OrderDate]),
          SEEK:([Orders].[OrderDate]='1998-02-26') ORDERED FORWARD)
       |--Clustered Index Seek(OBJECT:([Orders].[PK_Orders]),
          SEEK:([Orders].[OrderID]=[Orders].[OrderID]) LOOKUP ORDERED FORWARD)
书签查询可以用在堆中,也可以用在聚集索引中,正如上所描述的,在SQL Server 2000中,堆上的书签查询与聚集索引上的书签查询是相同的,而在SQL Server 2005中,堆上的书签查询仍旧使用一个嵌套循环联接运算,代替了聚集索引查找,SQL Server使用一个叫做RID查询运算符.RID查询运算符包括在堆上进行书签查询的查找谓词,但是堆并不是一个索引,RID查询也不是一个索引查找.

fj.png23.JPG

fj.pngfff.JPG

fj.pngffff.JPG

fj.pngrid_lookup.jpg

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/355374/viewspace-495810/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/355374/viewspace-495810/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值