Operador do Dia – Bookmark Lookup
O operador de hoje, é um dos mais famosos, e comuns de visualizarmos nos planos de execução.
Eles mudaram bastante conforme o tempo, no SQL 2000 ele se chamava BookMark Lookup, já no SQL 2005 SP2 e 2008 ele é conhecido como Key Lookup. No modo texto do plano de execução ele é apresentado como Index Seek.
Ícone no SQL Server 2005 e 2008.
O Key Lookup é utilizado em tabelas que contem um índice Cluster, o SQL utiliza este operador para localizar dados em um índice cluster, dados estes que não pertencem a um determinado índice nonclustered.
Eu escrevi um artigo falando sobre sua funcionalidade e com alguns exemplos no link abaixo.
Eu mencionei que ele é famoso porque a bastante coisa sobre ele na internet.
Quando você encontrar ele em um plano de execução, de cara você sabe que tem uma chance de otimizar a consulta criando um Covered Index, ou seja, criar um índice nonclustered que irá compor todas as colunas do seu select.
Funcionamento:
Vamos usar o seguinte script.
CREATE TABLE TabTeste (ID Int PRIMARY KEY, Nome VarChar(80), SobreNome VarChar(80))
CREATE NONCLUSTERED INDEX ix_Teste ON TABTeste(Nome)
SELECT * FROM TabTeste WITH(index = ix_Teste)
WHERE Nome = ‘Fabiano’
SELECT * FROM TabTeste WITH(index = ix_Teste) WHERE Nome = ‘Fabiano’
|–Nested Loops(Inner Join, OUTER REFERENCES:([dbo].[TabTeste].[ID]))
|–Index Seek(OBJECT:([dbo].[TabTeste].[ix_Teste]), SEEK:([dbo].[TabTeste].[Nome]=’Fabiano’) ORDERED FORWARD)
|–Clustered Index Seek(OBJECT:([dbo].[TabTeste].[PK__TabTeste__3214EC27131C685F]), SEEK:( [dbo].[TabTeste].[ID]= [dbo].[TabTeste].[ID]) LOOKUP ORDERED FORWARD)
Na consulta acima, o SQL irá utilizar o índice ix_teste para pegar os dados da tabela TabTeste, porém no índice ix_teste eu só tenho os dados das colunas Nome, e ID (todo índice nonclustered também tem a chave do índice cluster), mas na consulta estou pedindo todas as colunas (*).
Neste caso o SQL irá ler as colunas ID e Nome do índice ix_teste e o valor de ID e Sobrenome do índice Cluster que é a PK. Depois de ler os valores, ele pega os 2 ID e faz um Join para “juntar” qual Sobrenome pertence a qual ID e Nome, por fim retornando os dados para o Select.