I have a 2019 SQL Server with a database with 'FORCE PARAMETERIZTION' set to true and a nightly job which does sp_updatestats on it.
One of the application has a feature which has two modes, a "operational" mode and a "test" mode. In the "test" mode, the data distribution is really skewed as compared to the "operational mode" where the datadistribution is uniform.
If the application is used early morning in the "operational mode" first by a user, a new plan is created by the SQL server due to the previous nights update stats. This plan is good for the "operational mode" & acceptable for the "test" mode but since the "test" mode is rarely used, there are no complaints.
But If the appliation is used in the "test" mode first thing in the morning, a plan is created which is good for the skewed data but terrible for the case with the "operational mode". As a result, the site experiences poor performance throught the day.
The application is a black box and cannot be updated. My thoughts are to introduce a hack with the update stats job wherein a SQL in the "operational mode" would be executed. This way, irrespective of whether the user uses either mode, performance will be good the next day.
But the DMV shows that there are 2 plans in the cache, one created by the nightly job and the other from the application.
The one created by the application has huge number of execution counts against it while the other has only one. The query_hash, plan_hash, even the sql_handle is the same on both entries. Only the plan_handle is different. When I examine the SET options in the plan XML, they are exactly the same. The only differences are the parameters used to create the plan and MaxCompileMemory values.
I would like to know why the SQL Server chose to create new plan for the query from the application even though it could have used the one from the nightly job. And it preferred to use the one created by the application repeatedly.
I know the relation between the sql_handle and plan_handle is 1:N but in this particular case, everything is the same (apparently). The SET options are the same, the table statistics going as input to the plans are the same, the query in the job is executed when there is no one around using the application.
Any inputs appreciated.
The eventual goal is to introduce a plan guide but I feel I need to understand the reasons for this behavior before trying trying to introduce a plan guide