Query performance with date parameters

I have query performance issues when using date parameters in a stored procedure.  The proc takes 15 minutes with hard-coded date values but well over an hour with parameters. I was calling it from SSIS and had trouble passing the variables as datetime2. So I was passing as varchar and handling the conversion in the proc.  Then I took SSIS out of it as i tried to debug. I've been searching for quite some time and I can't get anything to work. This is basically where I've left off.  (SQL2016)

EXEC dbo.GetData @ObsStartDt = '1/1/2017', @ObsEndDt = '12/31/2017'



CREATE PROCEDURE [dbo].[GetData] @ObsStartDt varchar(10) = NULL, @ObsEndDt varchar(10) = NULL
AS

BEGIN TRY  
SET NOCOUNT ON;


declare @StartDT datetime2  
declare @EndDt datetime2

set @StartDT = cast(@ObsStartDt as datetime2)
set @EndDt = cast(@ObsEndDt as datetime2)

select  <stuff)

from HealthPlanDM.MED_CLAIMS_FACT a
join HealthPlanDM.MEMBER_DEMO_DIM b
on a.MEM_DEMO_KEY = b.MEM_DEMO_KEY
join HealthPlanDM.PRODUCT_DIM c
on a.PROD_KEY = c.PROD_KEY      
join HealthPlanDM.DIAGNOSIS_DIM d
on a.DIAG_KEY = d.DIAG_KEY
join HealthPlanDM.PROCEDURE_DIM e
on a.PROC_KEY = e.PROC_KEY
join HealthPlanDM.SERVICING_PROV_DIM f
on a.SERV_PROV_KEY = f.SERV_PROV_KEY
join      HealthPlanDM.POS_DIM g
on a.POS_KEY = g.POS_KEY
join      HealthPlanDM.DRG_DIM h
on a.DRG_KEY = h.DRG_KEY
join HealthPlanDM.TOS_DIMBASE i
on a.TOS_KEY = i.TOS_KEY
join devwork.ACG_PATIENT_EXTRACT1 P                  
on b.MEM_ID = P.patient_id  
left outer join [Provider].NPI_REGISTRYBASE REG
on f.SERV_PROV_NPI = REG.NPI
left outer join DevWork.TAXONOMY_XWALK TAX
on REG.PrimaryTaxonomyCD = TAX.TAXONOMY_CODE
where c.PLAN_CODE <> 'MHACO'  and    
 a.ALL_AMT IS NOT NULL                                                            
and a.DOS between  @StartDT and @EndDt

OPTION (RECOMPILE)

end try
LVL 1
jvoconnellAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

David ToddSenior Database AdministratorCommented:
Hi,

What you've done in the procedure is to disable parameter sniffing, so your query plan is generic rather than taking the parameter values into account.

All that to say this: Figure out how to pass those values as datetime2 into this procedure. One way that comes to mind is to call a wrapper procedure from SSIS that does the conversion and calls the core procedure. Something else to try is to do the conversion in the where clause.

Can I recommend that you NOT use between with datetime date in your where clause. Can I recommend the following:
where
    c.PLAN_CODE <> 'MHACO'  
    and a.ALL_AMT IS NOT NULL                                                            
    and a.DOS >= @StartDT
    and a.DOS < dateadd( day, @EndDt, 1 )

The other things to point out is that the != means that your where clause may be non-sargable - which means that SQL has difficulties using the best query plans and running faster.

HTH
  David

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Scott PletcherSenior DBACommented:
What data type is a.DOS ?
If it's datetime2, then you're ok with the param being dateetime2.  
If it's datetime, you're much better off using datetime as the param type as well.

As to overall performance, if you (almost) always have a WHERE on DOS for table:
HealthPlanDM.MED_CLAIMS_FACT
then the best way to gain performance is to cluster that table on DOS.  That will result in better query performance overall, as long as the data type of the variable being compared to DOS is at least remotely compatible.
Dung DinhDBA and Business Intelligence DeveloperCommented:
Can you attach the Actual Execution Plan to see what happened?
jvoconnellAuthor Commented:
Thank you all for giving your time to assist. As always, it is very much appreciated. I've spent a long time on this and the suggestion to not user the "between" operator did the trick. It is performing very well. The query suggestion supplied works great. Thanks to all!!
Scott PletcherSenior DBACommented:
Strange, since that change alone shouldn't affect performance at all, either for good or bad.   Something else must have changed.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft SQL Server

From novice to tech pro — start learning today.