Self join to eliminate Key LookUp.
ChatGPT my excelent prompting.

Self join to eliminate Key LookUp.

A Key Lookup retrieves values from the clustered index using the primary key.

It occurs when a non-clustered index is used for seeking, but some required columns (e.g., in SELECT or ORDER BY) are missing from the index.

If many rows are returned, Key Lookups can slow down a query. Adding included columns to the index can prevent this, but I'll show an alternative solution below.


I will use the StackOverflow2013 database.

Existing Non clustered index.

DROP INDEX IF EXISTS Posts.IX_Posts_MUSQL_01;

CREATE INDEX IX_Posts_MUSQL_01 ON Posts(PostTypeId, OwnerUserid, Score);Query with Lookup.        

Query that will use a Key Lookup to get the needed columns (p.*).

/*Clean up any cached execution plans*/
DBCC DROPCLEANBUFFERS;

DECLARE
    @PostTypeId BIGINT = 1;

SELECT TOP (500)
    u.DisplayName
    , p.*
FROM 
    dbo.Posts p
JOIN
    dbo.Users u
        ON u.Id = p.OwnerUserId
WHERE
    p.Score >= 2
    AND p.PostTypeId = @PostTypeId;        

Execution plan (total execution time 3 sec ish). The Nested Loops join must run a Key lookup for each row.


Article content

Query with self join.

/*Clean up any cached execution plans*/
DBCC DROPCLEANBUFFERS;

DECLARE
    @PostTypeId BIGINT = 1;

SELECT TOP (500)
    u.DisplayName
    , p2.*
FROM 
    dbo.Posts p
INNER JOIN
    Posts p2
        ON p2.Id = p.Id
JOIN
    dbo.Users u
        ON u.Id = p.OwnerUserId
WHERE
    p.Score >= 2
    AND p.PostTypeId = 1;        

Execution plan (total execution time 0.2 sec ish). The Nested Loops join can seek all needed columns in the clustered index.


Article content


i sooo wona dom sqli

Like
Reply
Micael Uthas

Freelance SQL Server Specialist | 20+ Years in Jeeves ERP Adaptations, SQL Dev. With Extensive Enterprise Knowledge. | Trainer in T-SQL & Jeeves Development | Helping You Boost Jeeves Performance & Utilization

2mo

If you need help with this type of work, feel free to reach out!

Like
Reply

To view or add a comment, sign in

More articles by Micael Uthas

  • Dynamic SQL, using QUOTENAME

    Use QUOTENAME for single quoting, it makes code readable and help to prevent SQL injection problems. The function…

  • string_split is as bad as table variables.

    Database: StackOverflow2013 COMPATIBILITY_LEVEL: 160 The bad way. Executionplan: Estimation from string_split = 50 but…

    1 Comment
  • ROLLBACK Once, COMMIT Each!

    In SQL Server ROLLBACK TRANSACTION affects all open transactions for the session. COMMIT TRANSACTION affects the latest…

  • Datatype length!

    Make sure to match parameters length with the column´s length. Don´t do this! Complicated execution plan and i Filter…

    2 Comments
  • Indexes and memory.

    In this article, I will demonstrate how indexing can significantly reduce memory consumption, allowing resources to be…

  • Batchloading data to Azure fabric from Jeeves using Heap and RID.

    The problem One of my clients wanted to upload data to Microsoft fabric from their ERP (Jeeves). They didn´t want to…

    3 Comments
  • Deleted rows are Ghost in SQL Server

    SQL SERVER does not remove rows from a page when you delete them, instead it´s marked for delete or "ghosted". A…

  • The issue with TRY CATCH in T-SQL.

    Try catch blocks in T-SQL are very useful for handeling errors in your code but there are some stuff you need to…

  • ORM and filtered indexes.

    I´m no big fan of ORM, they have their upsides but for me as a SQL Server nerd it creates more issues then god stuff…

  • INLINE FILTERED INDEX CREATION BUG!

    One feauture in most DBRM´s is the computed column feauture and it is very useful but you cant use it in indexes. The…

    1 Comment

Insights from the community

Others also viewed

Explore topics