Eliminate key lookup in execution planHow (and why) does TOP impact an execution plan?Eliminate Key Lookup (Clustered) operator that slows down performanceWhy would optimiser choose Clustered Index + Sort instead of Non-Clustered Index?Key Lookup and Full-text indexKey lookup partition pruningSHOWPLAN does not display a warning but “Include Execution Plan” does for the same querydeteriorating stored procedure running timesComparison between A non-clustered primary key and a covering index in terms of performanceEliminate Key Lookup (Clustered) operator that slows down performanceCan't reduce cost of query plan and get rid of Key Lookup because of cursorCovering Index Changes Execution Plan but is not usedWhy does MSSQL choose scan in execution plan?
LWC: Is it safe to rely on window.location.href to get the page url?
I was reported to HR as being a satan worshiper
How to animate a function plot
Can UV radiation be safe for the skin?
Why is there no Disney logo in MCU movies?
Where should I draw the line on follow up questions from previous employer
What is a "hashed transaction" in SQL Server Replication terminology?
Can inductive kick be discharged without freewheeling diode, in this example?
“all of who” or “all of whom”?
Group riding etiquette
How were US credit cards verified in-store in the 1980's?
Moscow SVO airport, how to avoid scam taxis without pre-booking?
Necessity of tenure for lifetime academic research
math mode in ticks ( tikzpicture )
Which is the correct version of Mussorgsky's Pictures at an Exhibition?
What caused the end of cybernetic implants?
Why did I get UK entry stamps in my British passport?
Is the word 'mistake' a concrete or abstract noun?
Ask one verbal question to figure out who is blind and who is mute among three persons
Are sweatpants frowned upon on flights?
Under GDPR can I avoid divulging a customer's data to the government?
Can I leave a large suitcase at TPE during a 4-hour layover, and pick it up 4.5 days later when I come back to TPE on my way to Taipei downtown?
In what language did Túrin converse with Mím?
Cheap oscilloscope showing 16 MHz square wave
Eliminate key lookup in execution plan
How (and why) does TOP impact an execution plan?Eliminate Key Lookup (Clustered) operator that slows down performanceWhy would optimiser choose Clustered Index + Sort instead of Non-Clustered Index?Key Lookup and Full-text indexKey lookup partition pruningSHOWPLAN does not display a warning but “Include Execution Plan” does for the same querydeteriorating stored procedure running timesComparison between A non-clustered primary key and a covering index in terms of performanceEliminate Key Lookup (Clustered) operator that slows down performanceCan't reduce cost of query plan and get rid of Key Lookup because of cursorCovering Index Changes Execution Plan but is not usedWhy does MSSQL choose scan in execution plan?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I have the following query:
DECLARE @p__linq__0 UNIQUEIDENTIFIER
SET @p__linq__0 = '... some guid ...'
SELECT TOP 1
[EventId] AS [EventId],
[DateCreated] AS [DateCreated],
[LocationId] AS [LocationId],
[SourceName] AS [SourceName],
[SourceState] AS [SourceState],
[Priority] AS [Priority],
[EventDescription] AS [EventDescription],
[FirstTrigger] AS [FirstTrigger]
FROM [dbo].[Watchdog]
WHERE
[LocationId] = @p__linq__0
AND
[FirstTrigger] = 1
ORDER BY [DateCreated] DESC
Watchdog
table defines 2 indecies:
- Clustered index on
EventId
primary key column - Unclustered index on
DateCreated
column
This is actual execution plan for the query:
Reading other posts on how to eliminate key lookup I added another non-clustered index which includes all columns from SELECT
CREATE NONCLUSTERED INDEX [LocationId_FirstTrigger] ON [dbo].[Watchdog]
(
[LocationId] ASC,
[FirstTrigger] ASC
)
INCLUDE ( [EventId],
[DateCreated],
[SourceName],
[SourceState],
[Priority],
[EventDescription]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
GO
However, this didn't help and actual execution plan is the same. If I look at key lookup the output is actually included in newly added non clustered index.
My question is, why it's still doing key lookup
instead of index scan/seek ?
UPDATE
Following some suggestions in the comments, I dropped newly created non clustered index & instead recreated non clustered index on DateCreated
column including columns from SELECT
.
Now execution plan is the following:
Also query execution time dropped from 1+ minute to few seconds (this table has 18+ million rows).
Does this mean key lookup was done due to ORDER BY
on non-clustered index ?
sql-server sql-server-2012 query-performance execution-plan
add a comment |
I have the following query:
DECLARE @p__linq__0 UNIQUEIDENTIFIER
SET @p__linq__0 = '... some guid ...'
SELECT TOP 1
[EventId] AS [EventId],
[DateCreated] AS [DateCreated],
[LocationId] AS [LocationId],
[SourceName] AS [SourceName],
[SourceState] AS [SourceState],
[Priority] AS [Priority],
[EventDescription] AS [EventDescription],
[FirstTrigger] AS [FirstTrigger]
FROM [dbo].[Watchdog]
WHERE
[LocationId] = @p__linq__0
AND
[FirstTrigger] = 1
ORDER BY [DateCreated] DESC
Watchdog
table defines 2 indecies:
- Clustered index on
EventId
primary key column - Unclustered index on
DateCreated
column
This is actual execution plan for the query:
Reading other posts on how to eliminate key lookup I added another non-clustered index which includes all columns from SELECT
CREATE NONCLUSTERED INDEX [LocationId_FirstTrigger] ON [dbo].[Watchdog]
(
[LocationId] ASC,
[FirstTrigger] ASC
)
INCLUDE ( [EventId],
[DateCreated],
[SourceName],
[SourceState],
[Priority],
[EventDescription]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
GO
However, this didn't help and actual execution plan is the same. If I look at key lookup the output is actually included in newly added non clustered index.
My question is, why it's still doing key lookup
instead of index scan/seek ?
UPDATE
Following some suggestions in the comments, I dropped newly created non clustered index & instead recreated non clustered index on DateCreated
column including columns from SELECT
.
Now execution plan is the following:
Also query execution time dropped from 1+ minute to few seconds (this table has 18+ million rows).
Does this mean key lookup was done due to ORDER BY
on non-clustered index ?
sql-server sql-server-2012 query-performance execution-plan
1
Maybe a hint: dba.stackexchange.com/questions/222987/…
– McNets
10 hours ago
add a comment |
I have the following query:
DECLARE @p__linq__0 UNIQUEIDENTIFIER
SET @p__linq__0 = '... some guid ...'
SELECT TOP 1
[EventId] AS [EventId],
[DateCreated] AS [DateCreated],
[LocationId] AS [LocationId],
[SourceName] AS [SourceName],
[SourceState] AS [SourceState],
[Priority] AS [Priority],
[EventDescription] AS [EventDescription],
[FirstTrigger] AS [FirstTrigger]
FROM [dbo].[Watchdog]
WHERE
[LocationId] = @p__linq__0
AND
[FirstTrigger] = 1
ORDER BY [DateCreated] DESC
Watchdog
table defines 2 indecies:
- Clustered index on
EventId
primary key column - Unclustered index on
DateCreated
column
This is actual execution plan for the query:
Reading other posts on how to eliminate key lookup I added another non-clustered index which includes all columns from SELECT
CREATE NONCLUSTERED INDEX [LocationId_FirstTrigger] ON [dbo].[Watchdog]
(
[LocationId] ASC,
[FirstTrigger] ASC
)
INCLUDE ( [EventId],
[DateCreated],
[SourceName],
[SourceState],
[Priority],
[EventDescription]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
GO
However, this didn't help and actual execution plan is the same. If I look at key lookup the output is actually included in newly added non clustered index.
My question is, why it's still doing key lookup
instead of index scan/seek ?
UPDATE
Following some suggestions in the comments, I dropped newly created non clustered index & instead recreated non clustered index on DateCreated
column including columns from SELECT
.
Now execution plan is the following:
Also query execution time dropped from 1+ minute to few seconds (this table has 18+ million rows).
Does this mean key lookup was done due to ORDER BY
on non-clustered index ?
sql-server sql-server-2012 query-performance execution-plan
I have the following query:
DECLARE @p__linq__0 UNIQUEIDENTIFIER
SET @p__linq__0 = '... some guid ...'
SELECT TOP 1
[EventId] AS [EventId],
[DateCreated] AS [DateCreated],
[LocationId] AS [LocationId],
[SourceName] AS [SourceName],
[SourceState] AS [SourceState],
[Priority] AS [Priority],
[EventDescription] AS [EventDescription],
[FirstTrigger] AS [FirstTrigger]
FROM [dbo].[Watchdog]
WHERE
[LocationId] = @p__linq__0
AND
[FirstTrigger] = 1
ORDER BY [DateCreated] DESC
Watchdog
table defines 2 indecies:
- Clustered index on
EventId
primary key column - Unclustered index on
DateCreated
column
This is actual execution plan for the query:
Reading other posts on how to eliminate key lookup I added another non-clustered index which includes all columns from SELECT
CREATE NONCLUSTERED INDEX [LocationId_FirstTrigger] ON [dbo].[Watchdog]
(
[LocationId] ASC,
[FirstTrigger] ASC
)
INCLUDE ( [EventId],
[DateCreated],
[SourceName],
[SourceState],
[Priority],
[EventDescription]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
GO
However, this didn't help and actual execution plan is the same. If I look at key lookup the output is actually included in newly added non clustered index.
My question is, why it's still doing key lookup
instead of index scan/seek ?
UPDATE
Following some suggestions in the comments, I dropped newly created non clustered index & instead recreated non clustered index on DateCreated
column including columns from SELECT
.
Now execution plan is the following:
Also query execution time dropped from 1+ minute to few seconds (this table has 18+ million rows).
Does this mean key lookup was done due to ORDER BY
on non-clustered index ?
sql-server sql-server-2012 query-performance execution-plan
sql-server sql-server-2012 query-performance execution-plan
edited 10 hours ago
Michael
asked 11 hours ago
MichaelMichael
1263 bronze badges
1263 bronze badges
1
Maybe a hint: dba.stackexchange.com/questions/222987/…
– McNets
10 hours ago
add a comment |
1
Maybe a hint: dba.stackexchange.com/questions/222987/…
– McNets
10 hours ago
1
1
Maybe a hint: dba.stackexchange.com/questions/222987/…
– McNets
10 hours ago
Maybe a hint: dba.stackexchange.com/questions/222987/…
– McNets
10 hours ago
add a comment |
2 Answers
2
active
oldest
votes
You should move the column DateCreated
to the key columns in the index LocationId_FirstTrigger
.
Then you will get a seek on LocationId
and FirstTrigger
and a backward scan of the index to locate the row with highest value of DateCreated
according to select top(1) ... order by DateCreated desc
.
CREATE NONCLUSTERED INDEX [LocationId_FirstTrigger] ON [dbo].[Watchdog]
(
[LocationId] ASC,
[FirstTrigger] ASC,
[DateCreated]
)
INCLUDE (
[EventId],
[SourceName],
[SourceState],
[Priority],
[EventDescription]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
If the index is not ordered by DateCreated
SQL Server will have to read all matching rows and sort them to know what row to return.
add a comment |
My question is, why it's still doing key lookup instead of index scan/seek ?
The query specifies that results should be ordered by DateCreated
. Since you already had a nonclustered index on DateCreated
, the optimizer decided that the cost of doing key lookups was lower than sorting all of the data by DateCreated
.
Does this mean key lookup was done due to ORDER BY on non-clustered index ?
Essentially, yes. It was estimated to be cheaper* to read the data in the required order, and get any additional fields through a key lookup, rather than reading all of the fields from a single index and then sorting it by DateCreated
.
You could confirm this by comparing the estimated costs between
- the original query (with the original indexes), and
- the original query with an index hint
The index hint would be like this on the FROM
line:
FROM [dbo].[Watchdog] WITH (INDEX (LocationId_FirstTrigger))
This should produce a plan with no key lookups (since LocationId_FirstTrigger
is covering for that query), and a Sort
operator. I'd expect the "Estimated Cost" to be higher, thus the other plan was chosen.
* To explain the optimizer's choice here:
The TOP (1)
in your query means the optimizer sets a row goal, meaning the plan is geared toward producing one row quickly. The optimizer expects to find one row from the Index Scan matching your LocationId
predicate very quickly, since it assumes values are distributed uniformly. This may or may not be true in reality. The cost of one Key Lookup following the Index Scan is pretty small.
The scan + lookup option therefore looks cheaper to the optimizer than finding matches using LocationId_FirstTrigger
and sorting. You can turn the row goal logic off for the query as a test by adding an OPTION (QUERYTRACEON 4138)
hint. You will likely find the optimizer then chooses the LocationId_FirstTrigger
index without an index hint.
Still, the best alternative is to modify your index as Mikael Eriksson suggests.
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "182"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f246649%2feliminate-key-lookup-in-execution-plan%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You should move the column DateCreated
to the key columns in the index LocationId_FirstTrigger
.
Then you will get a seek on LocationId
and FirstTrigger
and a backward scan of the index to locate the row with highest value of DateCreated
according to select top(1) ... order by DateCreated desc
.
CREATE NONCLUSTERED INDEX [LocationId_FirstTrigger] ON [dbo].[Watchdog]
(
[LocationId] ASC,
[FirstTrigger] ASC,
[DateCreated]
)
INCLUDE (
[EventId],
[SourceName],
[SourceState],
[Priority],
[EventDescription]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
If the index is not ordered by DateCreated
SQL Server will have to read all matching rows and sort them to know what row to return.
add a comment |
You should move the column DateCreated
to the key columns in the index LocationId_FirstTrigger
.
Then you will get a seek on LocationId
and FirstTrigger
and a backward scan of the index to locate the row with highest value of DateCreated
according to select top(1) ... order by DateCreated desc
.
CREATE NONCLUSTERED INDEX [LocationId_FirstTrigger] ON [dbo].[Watchdog]
(
[LocationId] ASC,
[FirstTrigger] ASC,
[DateCreated]
)
INCLUDE (
[EventId],
[SourceName],
[SourceState],
[Priority],
[EventDescription]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
If the index is not ordered by DateCreated
SQL Server will have to read all matching rows and sort them to know what row to return.
add a comment |
You should move the column DateCreated
to the key columns in the index LocationId_FirstTrigger
.
Then you will get a seek on LocationId
and FirstTrigger
and a backward scan of the index to locate the row with highest value of DateCreated
according to select top(1) ... order by DateCreated desc
.
CREATE NONCLUSTERED INDEX [LocationId_FirstTrigger] ON [dbo].[Watchdog]
(
[LocationId] ASC,
[FirstTrigger] ASC,
[DateCreated]
)
INCLUDE (
[EventId],
[SourceName],
[SourceState],
[Priority],
[EventDescription]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
If the index is not ordered by DateCreated
SQL Server will have to read all matching rows and sort them to know what row to return.
You should move the column DateCreated
to the key columns in the index LocationId_FirstTrigger
.
Then you will get a seek on LocationId
and FirstTrigger
and a backward scan of the index to locate the row with highest value of DateCreated
according to select top(1) ... order by DateCreated desc
.
CREATE NONCLUSTERED INDEX [LocationId_FirstTrigger] ON [dbo].[Watchdog]
(
[LocationId] ASC,
[FirstTrigger] ASC,
[DateCreated]
)
INCLUDE (
[EventId],
[SourceName],
[SourceState],
[Priority],
[EventDescription]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
If the index is not ordered by DateCreated
SQL Server will have to read all matching rows and sort them to know what row to return.
answered 8 hours ago
Mikael ErikssonMikael Eriksson
19k3 gold badges47 silver badges89 bronze badges
19k3 gold badges47 silver badges89 bronze badges
add a comment |
add a comment |
My question is, why it's still doing key lookup instead of index scan/seek ?
The query specifies that results should be ordered by DateCreated
. Since you already had a nonclustered index on DateCreated
, the optimizer decided that the cost of doing key lookups was lower than sorting all of the data by DateCreated
.
Does this mean key lookup was done due to ORDER BY on non-clustered index ?
Essentially, yes. It was estimated to be cheaper* to read the data in the required order, and get any additional fields through a key lookup, rather than reading all of the fields from a single index and then sorting it by DateCreated
.
You could confirm this by comparing the estimated costs between
- the original query (with the original indexes), and
- the original query with an index hint
The index hint would be like this on the FROM
line:
FROM [dbo].[Watchdog] WITH (INDEX (LocationId_FirstTrigger))
This should produce a plan with no key lookups (since LocationId_FirstTrigger
is covering for that query), and a Sort
operator. I'd expect the "Estimated Cost" to be higher, thus the other plan was chosen.
* To explain the optimizer's choice here:
The TOP (1)
in your query means the optimizer sets a row goal, meaning the plan is geared toward producing one row quickly. The optimizer expects to find one row from the Index Scan matching your LocationId
predicate very quickly, since it assumes values are distributed uniformly. This may or may not be true in reality. The cost of one Key Lookup following the Index Scan is pretty small.
The scan + lookup option therefore looks cheaper to the optimizer than finding matches using LocationId_FirstTrigger
and sorting. You can turn the row goal logic off for the query as a test by adding an OPTION (QUERYTRACEON 4138)
hint. You will likely find the optimizer then chooses the LocationId_FirstTrigger
index without an index hint.
Still, the best alternative is to modify your index as Mikael Eriksson suggests.
add a comment |
My question is, why it's still doing key lookup instead of index scan/seek ?
The query specifies that results should be ordered by DateCreated
. Since you already had a nonclustered index on DateCreated
, the optimizer decided that the cost of doing key lookups was lower than sorting all of the data by DateCreated
.
Does this mean key lookup was done due to ORDER BY on non-clustered index ?
Essentially, yes. It was estimated to be cheaper* to read the data in the required order, and get any additional fields through a key lookup, rather than reading all of the fields from a single index and then sorting it by DateCreated
.
You could confirm this by comparing the estimated costs between
- the original query (with the original indexes), and
- the original query with an index hint
The index hint would be like this on the FROM
line:
FROM [dbo].[Watchdog] WITH (INDEX (LocationId_FirstTrigger))
This should produce a plan with no key lookups (since LocationId_FirstTrigger
is covering for that query), and a Sort
operator. I'd expect the "Estimated Cost" to be higher, thus the other plan was chosen.
* To explain the optimizer's choice here:
The TOP (1)
in your query means the optimizer sets a row goal, meaning the plan is geared toward producing one row quickly. The optimizer expects to find one row from the Index Scan matching your LocationId
predicate very quickly, since it assumes values are distributed uniformly. This may or may not be true in reality. The cost of one Key Lookup following the Index Scan is pretty small.
The scan + lookup option therefore looks cheaper to the optimizer than finding matches using LocationId_FirstTrigger
and sorting. You can turn the row goal logic off for the query as a test by adding an OPTION (QUERYTRACEON 4138)
hint. You will likely find the optimizer then chooses the LocationId_FirstTrigger
index without an index hint.
Still, the best alternative is to modify your index as Mikael Eriksson suggests.
add a comment |
My question is, why it's still doing key lookup instead of index scan/seek ?
The query specifies that results should be ordered by DateCreated
. Since you already had a nonclustered index on DateCreated
, the optimizer decided that the cost of doing key lookups was lower than sorting all of the data by DateCreated
.
Does this mean key lookup was done due to ORDER BY on non-clustered index ?
Essentially, yes. It was estimated to be cheaper* to read the data in the required order, and get any additional fields through a key lookup, rather than reading all of the fields from a single index and then sorting it by DateCreated
.
You could confirm this by comparing the estimated costs between
- the original query (with the original indexes), and
- the original query with an index hint
The index hint would be like this on the FROM
line:
FROM [dbo].[Watchdog] WITH (INDEX (LocationId_FirstTrigger))
This should produce a plan with no key lookups (since LocationId_FirstTrigger
is covering for that query), and a Sort
operator. I'd expect the "Estimated Cost" to be higher, thus the other plan was chosen.
* To explain the optimizer's choice here:
The TOP (1)
in your query means the optimizer sets a row goal, meaning the plan is geared toward producing one row quickly. The optimizer expects to find one row from the Index Scan matching your LocationId
predicate very quickly, since it assumes values are distributed uniformly. This may or may not be true in reality. The cost of one Key Lookup following the Index Scan is pretty small.
The scan + lookup option therefore looks cheaper to the optimizer than finding matches using LocationId_FirstTrigger
and sorting. You can turn the row goal logic off for the query as a test by adding an OPTION (QUERYTRACEON 4138)
hint. You will likely find the optimizer then chooses the LocationId_FirstTrigger
index without an index hint.
Still, the best alternative is to modify your index as Mikael Eriksson suggests.
My question is, why it's still doing key lookup instead of index scan/seek ?
The query specifies that results should be ordered by DateCreated
. Since you already had a nonclustered index on DateCreated
, the optimizer decided that the cost of doing key lookups was lower than sorting all of the data by DateCreated
.
Does this mean key lookup was done due to ORDER BY on non-clustered index ?
Essentially, yes. It was estimated to be cheaper* to read the data in the required order, and get any additional fields through a key lookup, rather than reading all of the fields from a single index and then sorting it by DateCreated
.
You could confirm this by comparing the estimated costs between
- the original query (with the original indexes), and
- the original query with an index hint
The index hint would be like this on the FROM
line:
FROM [dbo].[Watchdog] WITH (INDEX (LocationId_FirstTrigger))
This should produce a plan with no key lookups (since LocationId_FirstTrigger
is covering for that query), and a Sort
operator. I'd expect the "Estimated Cost" to be higher, thus the other plan was chosen.
* To explain the optimizer's choice here:
The TOP (1)
in your query means the optimizer sets a row goal, meaning the plan is geared toward producing one row quickly. The optimizer expects to find one row from the Index Scan matching your LocationId
predicate very quickly, since it assumes values are distributed uniformly. This may or may not be true in reality. The cost of one Key Lookup following the Index Scan is pretty small.
The scan + lookup option therefore looks cheaper to the optimizer than finding matches using LocationId_FirstTrigger
and sorting. You can turn the row goal logic off for the query as a test by adding an OPTION (QUERYTRACEON 4138)
hint. You will likely find the optimizer then chooses the LocationId_FirstTrigger
index without an index hint.
Still, the best alternative is to modify your index as Mikael Eriksson suggests.
edited 7 hours ago
Paul White♦
58.8k16 gold badges307 silver badges484 bronze badges
58.8k16 gold badges307 silver badges484 bronze badges
answered 9 hours ago
Josh DarnellJosh Darnell
12.1k3 gold badges27 silver badges60 bronze badges
12.1k3 gold badges27 silver badges60 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f246649%2feliminate-key-lookup-in-execution-plan%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Maybe a hint: dba.stackexchange.com/questions/222987/…
– McNets
10 hours ago