I'm using Entity Framework for making a rather large query. Recently this query is failing due to timeout exceptions.
When I started investigating this issue I used LinqPad and directly copied the SQL output in SSMS and ran the query. This query returns within 1 second!
The query then looks like (only for illustration, the real query is much larger)
DECLARE @p__linq__0 DateTime2 = '2017-10-01 00:00:00.0000000'
DECLARE @p__linq__1 DateTime2 = '2017-10-31 00:00:00.0000000'
SELECT
[Project8].[Volgnummer] AS [Volgnummer],
[Project8].[FkKlant] AS [FkKlant],
-- rest omitted for brevity
Now I used SQL Profiler to capture the real SQL send to the server. The query is exactly the same with the difference that this query is encapsulated within a call to sp_executesql. Like this:
exec sp_executesql N'SELECT
[Project8].[Volgnummer] AS [Volgnummer],
[Project8].[FkKlant] AS [FkKlant],
-- rest omitted for brevity
',N'@p__linq__0 datetime2(7),@p__linq__1 datetime2(7)',
@p__linq__0='2017-10-01 00:00:00',@p__linq__1='2017-10-31 00:00:00'
When I copy/paste this query in SSMS it runs for 60 seconds and thus results in a timeout when using from EF with default settings!
I can't wrap my head around why this difference is occurring, as this is the same query, the only thing is, it is executed differently.
I read a lot about why EF uses sp_executesql and I understand why. I also read that sp_executesql is different from EXEC because it makes use of the queryplan cache, but I don't understand why the SQL optimizer has such difficulty in creating a performant query plan for the sp_executesql version whereas it is capable of creating a performant queryplan for the direct query version.
I'm not sure if the complete query itself adds to the question. If it does, let me know and I will make an edit.