My initial thoughts are that the view itself is the major issue, in
that it is ranking over the entire data set. Also that there is no
index that includes the DateCreated column, but I'm not sure how
useful that is for sorting.
That is exactly it, the window function is applied to the whole dataset to then be filtered by CustomerId
and rn=1
. See my previous answer here for more information.
With the CustomerId
filter predicate applied only when the data gets to the filter operator:
You could add OPTION(RECOMPILE)
to the select query with the filter to see the CustomerId
at runtime and filter before passing the data through the window function
SELECT * FROM vw_SyncDataRecent
WHERE CustomerId = 600528
OPTION(RECOMPILE);
Other methods as noted in my other answer are not using the view, using a tvf instead, not using a window function to do the filtering, ....
TVF example
CREATE FUNCTION dbo.[Fnc_SyncDataRecent]
(
@P1 INT
)
RETURNS TABLE
WITH SCHEMABINDING AS
RETURN
WITH Ranked AS (
SELECT
Id,
CustomerId,
CategoryId,
ROW_NUMBER() OVER (
PARTITION BY Id, CustomerId
ORDER BY DateCreated DESC) AS rn
FROM dbo.SyncData AS cb
)
SELECT Id, CustomerId, CategoryId
FROM Ranked
WHERE rn = 1 and CustomerId = @P1
SELECT * FROM dbo.[Fnc_SyncDataRecent](600528);
I would also add this index:
CREATE INDEX IX_CustomerID3
ON dbo.SyncData([CustomerId])
INCLUDE(CategoryId,ID,DateCreated);