My application is issuing the following query:
(@Id bigint,@contractNumber nvarchar(12))
Select top 1 *
From ReceivableCut c with (nolock)
Where 1=1
And c.ReceivableCutIndicator = 0
And c.OrgId = @Id
And c.ContractNumber = @contractNumber
And exists (select '1' from Receivable r with(nolock) where r.OrgId = c.OrgId and r.ReceivableNumber = c.ReceivableNumber)
Order by c.ReceivableNumber desc
and when I access Azure Database query performance insight, I get that the query with the highest consumption is:
(@Id bigint,@contractNumber nvarchar(12))
Select top 1 *
From ReceivableCut c with (nolock)
Where 1=1
And c.ReceivableCutIndicator = 0
And c.OrgId = @Id
And c.ContractNumber = @contractNumber
And exists (select '1' from Receivable r with(nolock) where r.OrgId = c.OrgId and r.ReceivableNumber = c.ReceivableNumber)
Order by c.ReceivableNumber desc
option (PLAN PER VALUE(ObjectID = 0, QueryVariantID = 3, predicate_range([DB_MERCHANTS_PAYMENT].[dbo].[ReceivableCut].[OrgId] = @Id, 100.0, 1000000.0)))
That query is not issued anywhere in my code, and it runs for the exactly the amount of times I expect my query to run.
My ORM (EFCore) is not issuing this new query, so WHERE is this coming from?!? the major issue is that @Id
is always 63
so that hint is COMPLETELY wrong!!!
My application is issuing the following query:
(@Id bigint,@contractNumber nvarchar(12))
Select top 1 *
From ReceivableCut c with (nolock)
Where 1=1
And c.ReceivableCutIndicator = 0
And c.OrgId = @Id
And c.ContractNumber = @contractNumber
And exists (select '1' from Receivable r with(nolock) where r.OrgId = c.OrgId and r.ReceivableNumber = c.ReceivableNumber)
Order by c.ReceivableNumber desc
and when I access Azure Database query performance insight, I get that the query with the highest consumption is:
(@Id bigint,@contractNumber nvarchar(12))
Select top 1 *
From ReceivableCut c with (nolock)
Where 1=1
And c.ReceivableCutIndicator = 0
And c.OrgId = @Id
And c.ContractNumber = @contractNumber
And exists (select '1' from Receivable r with(nolock) where r.OrgId = c.OrgId and r.ReceivableNumber = c.ReceivableNumber)
Order by c.ReceivableNumber desc
option (PLAN PER VALUE(ObjectID = 0, QueryVariantID = 3, predicate_range([DB_MERCHANTS_PAYMENT].[dbo].[ReceivableCut].[OrgId] = @Id, 100.0, 1000000.0)))
That query is not issued anywhere in my code, and it runs for the exactly the amount of times I expect my query to run.
My ORM (EFCore) is not issuing this new query, so WHERE is this coming from?!? the major issue is that @Id
is always 63
so that hint is COMPLETELY wrong!!!
1 Answer
Reset to default 0Agreed with @Charlieface, the difference between the queries is due to Azure SQL Database's automated plan correction capability, known as Plan Forcing or automated Tuning. Automatic plan correction is an automatic tuning function that detects execution plan choice regression and automatically resolves the issue by reverting to the last known good plan.
- To Disable automatic plan correction using this command
ALTER DATABASE dbname SET AUTOMATIC_TUNING ( FORCE_LAST_GOOD_PLAN = OFF );
OPTION
s to the plan post-facto via Query Store and PSPO learn.microsoft/en-us/sql/relational-databases/performance/… . If PSPO is causing issues here then you need to look at the root cause, which is probably a lack of an indexReceivableCut (OrgId, ContractNumber, ReceivableNumber)
. Remove thosenolock
hints while you're at it. – Charlieface Commented Feb 3 at 15:35option
line is coming from, but it's a normal feature of PSPO – Charlieface Commented Feb 3 at 15:36option
itself is not an issue, it will only be used if the parameter value actually matches (which is what PSPO is for). Theoption
is a red herring, what you need to look at is the actual query plan and why it's slow. But for that, we need at a minimum all relevant table and index definitions, and please share the query plan via pastetheplan – Charlieface Commented Feb 3 at 17:44ALTER DATABASE dbname SET AUTOMATIC_TUNING ( FORCE_LAST_GOOD_PLAN = OFF );
Run your query again and check if the OPTION (PLAN PER VALUE...) disappears. If it does, then Azure was dynamically altering your plan. – Pratik Lad Commented Feb 11 at 7:18