0

I'm passing a TVP with 2 fields (a datetime and a varchar(3)) into a stored proc, and I'm trying to return all the table rows where the table's datetime column is either equal to one of the TVP datetimes or up to a couple of minutes earlier (I don't mind duplicates but would prefer without).

This is what I've come up with - it's currently very slow (~5 seconds!) and I'm not sure what to do to improve it. Index the table? Which column? AtTime?

I know it's a fiddly query as it needs to compute a range to look for before trying to match a row, so if there's an entirely different but preferable way to do this please let me know. Plus the input TVP has ~300 rows and the table itself has over 200k, so there's a lot of data to match and search.

CREATE PROCEDURE [dbo].[spGetPricesForDates]
    @tvp tvpType READONLY
AS
BEGIN
    SET NOCOUNT ON;

    SELECT S.AtTime, S.Underlying, S.Price
    FROM SourceTable S, @tvp T
    WHERE S.Underlying = T.Underlying   
    AND S.AtTime in (select AtTime
                    from SourceTable 
                    where AtTime 
                    between DATEADD(mi, -2, T.MyDate)
                    and T.MyDate)
END

edit I just realised my in query won't do what I want - I want to return the latest matching table date/price row per tvp row within a 2 minute range, whereas at the moment it'll give me everything that matches in that between set. I tried using MAX(AtTime) but that limits it to one possible match so I'm back to square 1.

Alex
  • 2,681
  • 3
  • 28
  • 43

1 Answers1

3

Try using this inner join:

SELECT S.AtTime, S.Underlying, S.Price
FROM SourceTable S
INNER JOIN @tvp T ON (S.Underlying = T.Underlying 
        AND (S.AtTime BETWEEN DATEADD(mi, -2, T.MyDate) AND T.MyDate))
TheVillageIdiot
  • 40,053
  • 20
  • 133
  • 188