Использование столбца табличных параметров в хранимой процедуре -

Я передаю TVP с двумя полями (datetime и varchar(3)) в хранимую процедуру и пытаюсь вернуть все строки таблицы, в которых столбец даты и времени таблицы либо равен одному из значений даты и времени TVP, либо до на пару минут раньше (я не против дубликатов, но предпочел бы без них).

Вот что я придумал - в настоящее время он очень медленный (~ 5 секунд!), И я не уверен, что нужно сделать, чтобы улучшить его. Индексировать таблицу? Какой столбец? AtTime?

Я знаю, что это сложный запрос, так как он должен вычислить диапазон для поиска, прежде чем пытаться сопоставить строку, поэтому, если есть совершенно другой, но предпочтительный способ сделать это, сообщите мне. Кроме того, входная TVP имеет около 300 строк, а сама таблица имеет более 200 тыс., так что есть много данных для сопоставления и поиска.

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

изменить Я только что понял, что мой запрос in не будет делать то, что я хочу - я хочу вернуть последнюю совпадающую строку даты/цены таблицы для каждой строки tvp в пределах 2-минутного диапазона, тогда как на данный момент он даст мне все, что соответствует этому набору between. Я пытался использовать MAX(AtTime), но это ограничивает его одним возможным совпадением, поэтому я вернулся к квадрату 1.


comment
не могли бы вы добавить некоторые реалистичные данные?   -  person TheVillageIdiot    schedule 05.08.2011


Ответы (1)


Попробуйте использовать это 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))
person TheVillageIdiot    schedule 05.08.2011
comment
Я проверил, и он действительно дает значения в диапазоне от 2 минут меньше до прошедшей даты. - person TheVillageIdiot; 05.08.2011
comment
Это выглядит великолепно, намного проще и лаконичнее, чем мой запрос. Однако у него все еще есть проблема, заключающаяся в том, что я хотел бы получить последнее совпадение из предложения between. - person Alex; 05.08.2011
comment
@Alex, это также будет лучше, поскольку фильтрация выполняется на одном уровне только в пункте ON раздела INNER JOIN. - person TheVillageIdiot; 05.08.2011
comment
Как насчет SELECT MAX(S.AtTime), остальная часть запроса здесь. - person Michael Riley - AKA Gunny; 06.08.2011