Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Query Optimization

Author  Topic 

SamC
White Water Yakist

3467 Posts

Posted - 2005-05-30 : 09:17:55
In this article on bookmark lookups the author points out 3 methods of eliminating the lookup:

1 - Create a covering index - OK with this
2 - Remove the offending column [from the recordset result]
3 - Convert a non-clustered index to a clustered index

I am missing something on point 2. How can including another column of data in the result set (which is not involved in a JOIN or WHERE clause) create a bookmark lookup?

Here's the text from the article on point 2...

quote:
Remove the offending column
In the simple query below, the developer returned all the columns from the authors table when all the query asked for was the ID of the author.

SET STATISTICS PROFILE ON
GO

USE pubs
GO

--Find ID number for White, Johnson
SELECT *
FROM dbo.authors
WHERE au_lname = 'White'
AND au_fname = 'Johnson'
GO

Execution Plan (abridged)
StmtText
----------- ----------- ----------------------------------------------------------------------------------
SELECT * FROM [dbo].[authors] WHERE [au_lname]=@1 AND [au_fname]=@2 |--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([pubs].[dbo].[authors])) |--Index Seek(OBJECT:([pubs].[dbo].[authors].[aunmind]), SEEK:([authors].[au_lname]='White' AND [authors].[au_fname]='Johnson') ORDERED FORWARD)

Removing the additional, unneeded columns and only returning the au_id column will remove the bookmark lookup in this case

SET STATISTICS PROFILE ON
GO

USE pubs
GO

--Find ID number for White, Johnson
SELECT au_id
FROM dbo.authors
WHERE au_lname = 'White'
AND au_fname = 'Johnson'
GO

Execution Plan (abridged)
StmtText
----------- ----------- ----------------------------------------------------------------------------------
SELECT [au_id]=[au_id] FROM [dbo].[authors] WHERE [au_lname]=@1 AND [au_fname]=@2 |--Index Seek(OBJECT:([pubs].[dbo].[authors].[aunmind]), SEEK:([authors].[au_lname]=[@1] AND [authors].[au_fname]=[@2]) ORDERED FORWARD)

Bookmark lookups are often caused by additional columns being returned in the data set “just in case” they are needed at a later date. Developers should strive to only include columns in their result sets which are needed for the defined query requirements. Additional columns can always be added at a later date.

AndrewMurphy
Master Smack Fu Yak Hacker

2916 Posts

Posted - 2005-05-30 : 10:40:26
Say you have a non-clustered index covering (col1,col2). No bookmark lookup (to the raw data pages) are needed if the query only includes col1+col2. However if the data to be returned to the resultset included say col3 (which is not in the index)...then a bookmark lookup is needed...because it's not already been traversed. This col3 data is elsewhere (in the raw data pages)...and a bookmark lookup is needed to get from the index row to the raw data.
Go to Top of Page
   

- Advertisement -