SQL SERVER – Optimize Key Lookup by Creating Index with Include Columns

I love query tuning and performance tuning projects. In one of the recent Comprehensive Database Performance Health Check my client had a very interesting scenario where their queries were running pretty fast earlier but gradually started to run slow and eventually started to take over 10 minutes to execute. They reached out to me to tune their slow running query. While looking at the query execution plan, there is a big key lookup operation which was actually slowing down their query. I decided to create an index with include column on that table and resolve this issue.

Let us see how I did that with a real-world example.

First, let us create a test table.

-- Create a Sample Table
CREATE TABLE TestTable (ID INT, FirstName VARCHAR(100), LastName VARCHAR(100))

Next, populate the test table with sample data.

-- Insert Sample Data
INSERT INTO TestTable (ID, FirstName, LastName)
VALUES(1,'Pinal', 'Dave')
INSERT INTO TestTable (ID, FirstName, LastName)
VALUES(1,'Mike', 'Smith')
GO 10000

Right after that create one clustered index and non clustered index on the table.

-- Create Clustered index on column ID
-- Create nonclustered index on column FirstName
CREATE NONCLUSTERED INDEX IXTestTable_FirstName ON TestTable (FirstName)

Following that run our query with enabling actual execution plan. You can enable the actual execution plan by going into SSMS toolbar >> Query >> and “Include Actual Execution Plan”. Alternatively, you can also enable that by pressing CTRL + M.

Now you are ready to run the query. Right after running the query, open the execution plan.

-- Run a sample with execution plan CTRL + M
SELECT FirstName, LastName
FROM TestTable
WHERE FirstName = 'Pinal'

In the execution plan, you will notice that there is a key lookup in addition to usage of the index. SQL Server has to do key lookup when the index does not have all the necessary columns which query is requesting.

SQL SERVER - Optimize Key Lookup by Creating Index with Include Columns keylookup1

In this case you have two options 1) Either alter the original index and include the columns which are visible in the Output List. 2) Create a brand new index including the columns from the output list in the include part of the index.

-- Create a covering index with include column
CREATE NONCLUSTERED INDEX IXTestTable_FirstName_Include ON TestTable (FirstName)

Just for simplicity, I will be creating a new index in our example. Remember creating too many indexes on the table can slow down your index-related operations to multi-fold.

Right after creating the index, let us run the same query once again and check the execution plan.

-- Run a sample with execution plan
SELECT FirstName, LastName
FROM TestTable
WHERE FirstName = 'Pinal'

You can see in the execution plan there is no more key lookup and query also uses our newly created index.

After fixing the key lookup for my customer the query started to run from 11 minutes to 12 seconds. If you are also seeing a lot of key lookup in your query, you can follow my advice to tune your query.

Here is the script to clean up the object which we have created.

-- clean up
DROP Table TestTable

There are many similar tricks to tune your query we often discuss in our SQL Server Performance Tuning Practical Workshop.

Reference: Pinal Dave (https://blog.sqlauthority.com

Execution Plan, SQL Index, SQL Operator, SQL Scripts, SQL Server
Previous Post
SQL SERVER – How to Escape a Single Quote in SQL Server?
Next Post
SQL SERVER – Results of Dynamic SQL Into A Variable

Related Posts

1 Comment. Leave new

  • Celso Henrique Mendes Ferrreira
    September 22, 2021 7:34 pm

    Hi Pinal, I learned about Key Lookup in this post long time ago and this helped me a lot. Now I am facing a situation that I can’t understand. The execution plan is showing a Key Lookup, but there is no Output List. I really don’t know how to fix this.


Leave a ReplyCancel reply

Exit mobile version