I have a query that needs a plan guide, but I am having a hard time setting it up.
Query below from the procedure cache…
(@state nvarchar(14),
@jobName nvarchar(18),
@jobGroup nvarchar(28),
@oldState nvarchar(6))
UPDATE JOB_TRIGGERS
SET TRIGGER_STATE = @state
WHERE JOB_NAME = @jobName
AND JOB_GROUP = @jobGroup
AND TRIGGER_STATE = @oldState
SQL Server chooses to perform a clustered index scan vs a non clustered index seek. I am having sporadic deadlock issues with this update statement and a certain select statement on the table. I understand why SQL is choosing an clustered index scan on the table….Rows < 100 and PageCount < 25.
The table has a large of amount of activity, and since its a 3rd party product I don't have the ability to modify the query and supply an index hint. The query cost of using the non clustered index is more, but I believe it will improve concurrency based on testing….
I need to tell it to use the non clustered index below
WITH (INDEX (ix_jobname_jobgroup_triggerstate))
Help setting this up would be much appreciated..
Best Answer
Ideally, we would like to use a plan guide to add a
TABLE HINT
, so the guided query becomes:Unfortunately, this is not possible because the
UPDATE
is written without aFROM
clause:You can work around this by capturing the XML showplan for the equivalent:
Note this form of the query has a
FROM
clause to support the index hint. The query must be written exactly as above, without the usual alias for the target table.You can then use this XML (without the opening
<?xml version="1.0" encoding="utf-16"?>
) element as the@hints
parameter insp_create_plan_guide
.Example
Given the table and indexes:
The plan guide (using the captured XML from the index-hinted form above) is:
Submitting the query:
Gives the desired plan:
The plan properties show the plan guide was used:
You cannot just use the exact plan guide above - it is just an example that worked on the toy schema I created to reproduce your issue. Nevertheless, the general process outlined should work for you.