Reputation: 7254
I've got a quite complex view that has about 100 subqueries in it's definition.
Simple statement like:
SELECT * FROM MyView
take 2 seconds to generate the plan and execute query.Subsequent selects when the plan is cached take less than 1ms to execute.
This situation would be alright if I had only a couple of queries - performance hit only once is acceptable. The problem is that our ORM generates paging queries with parameters using CTE. Changing parameter values(pages) causes query plan recalculation - in this case this unfortunately takes about 4 seconds!
Let's add filtering, sorting and you get the idea of what happens..
What can I do to cut down the query plan creation times or make less of them or optimize this in any other manner?
@MartinSmith "SQL Server doesn't generate a plan for each parameter value except if the text has somehow changed"
I have a query like this (I've put stars here instead of more than 120 fields list):
DECLARE @low int = 20;
DECLARE @high int = 300;
WITH __actualSet
AS (
SELECT *
,ROW_NUMBER() OVER (
ORDER BY CURRENT_TIMESTAMP
) AS __rowcnt
FROM (
SELECT TOP 5000 *
FROM [dbo].[Project] [LPA_L1]
ORDER BY [LPA_L1].[CreatedOn] ASC
) AS _tmpSet
)
SELECT *
FROM __actualSet
WHERE [__rowcnt] > @low
AND [__rowcnt] <= @high
ORDER BY [__rowcnt] ASC
The first time I run this query ~4s. The second time ~1ms. When I change the param values - once again 4s. Maybe I'm misinterpreting something here?
Upvotes: 1
Views: 686
Reputation: 453047
To test in SSMS and reuse the same plan for different values you need to parameterise the query and execute it with sp_executesql
DECLARE @low int = 20;
DECLARE @high int = 300;
EXEC sp_executesql N'
WITH __actualSet
AS (
SELECT *
,ROW_NUMBER() OVER (
ORDER BY CURRENT_TIMESTAMP
) AS __rowcnt
FROM (
SELECT TOP 5000 *
FROM [dbo].[Project] [LPA_L1]
ORDER BY [LPA_L1].[CreatedOn] ASC
) AS _tmpSet
)
SELECT *
FROM __actualSet
WHERE [__rowcnt] > @low
AND [__rowcnt] <= @high
ORDER BY [__rowcnt] ASC
', N'@low INT, @high INT', @low = @low, @high = @high
Upvotes: 1