Проверка SQL, если диапазон дат превышает предел

В моей текущей хранимой процедуре я беру данные как из текущей таблицы данных, так и из таблицы архивных данных, где я «объединяю все» операторы Select из обоих источников.

Однако выполнение процедуры занимает много времени, поэтому я думал о способах оптимизации производительности. В моем случае я решил сделать условную проверку, существуют ли архивные данные или нет.

В моем случае данные архивируются, если они превышают 45-дневный лимит с текущего дня.

Для простоты ниже приведены 2 упрощенных случая. Если пользователь выбирает текущий месяц (в нашем случае май, а 02.05 — текущий день), диапазон дат будет только в текущем наборе данных, поскольку мы еще не нарушили 45-дневный лимит (между 01.05 и 31.05). . То же самое относится и к апрелю (диапазон дат между 01.04 и 30.04), так как 30 дней все еще находятся в 45-дневном лимите + 2 дня от мая.

Однако, если пользователь выбирает март в текущий день, некоторые из его дней превысят лимит в 45 дней (диапазон дат между 01.03 и 31.03), и в этом случае мне нужно будет просмотреть архивные данные. и объединить все с текущими данными.

Мои вопросы заключаются в следующем: Как лучше всего проверить, превышает ли диапазон дат ограничение в n дней?


person Vadzim Savenok    schedule 02.05.2017    source источник
comment
Вы имеете в виду что-то вроде этого? IF DATEADD(day,-45, DATEDIFF(d,0,GETDATE())) › @StartParam Запрос с объединением Else Запрос без объединения   -  person Kevin Johnson    schedule 02.05.2017
comment
Есть ли какая-либо фильтрация даты со стороны SP, которая запрашивает базу данных архива?   -  person Dan Bracuk    schedule 02.05.2017
comment
@DanBracuk Не совсем, я написал SP, в котором данные за 1 день перемещаются из Current в Archived по окончании дня.   -  person Vadzim Savenok    schedule 02.05.2017
comment
@KevinJohnson В значительной степени, и вы, возможно, только что подали мне идею ...   -  person Vadzim Savenok    schedule 02.05.2017
comment
Я вижу, вы говорите, что март может быть недоступен, поэтому, предполагая 45 дней как будущего, так и прошлого, это должно сработать, я думаю, это то, что вы хотите. выберите регистр, когда Square(DATEDIFF(DAY, Cast('02/05/2017' как дата), Cast('30/03/2017' как дата))) ‹ Square(45) then 'В пределах диапазона дат 45' else ' За пределами конца диапазона 45 дат --- Возведение в квадрат выполняется для удаления отрицательных значений.   -  person SCFi    schedule 02.05.2017


Ответы (1)


Если все так просто, вы можете использовать DATEDIFF( )

Возвращает количество (целое число со знаком) указанных границ даты, пересекаемых между указанными датой начала и датой окончания.

IF DATEDIFF(DAY, @StartDate, GETDATE()) < 45
BEGIN
    -- Pseudo query
    SELECT *
    FROM dbo.Table
    WHERE CreatedAt > @StartDate;
END;
ELSE
    -- Another pseudo query
    SELECT *
    FROM dbo.Table
    WHERE CreatedAt > @StartDate
    UNION ALL
    SELECT *
    FROM Archive.Table
    WHERE CreatedAt > @StartDate;
END;

В конечном счете, если вы хотите избежать условных операторов, я бы сказал, что вы можете создать покрывающий индекс в своей архивной таблице (я не уверен, насколько он велик), где ваша метка времени будет первым ключом. Наличие этого SQL Server будет эффективно искать по этому индексу, и ваш код будет легче поддерживать и читать.

Что-то вроде этого:

SELECT *
FROM (
    SELECT *
    FROM dbo.Table
    UNION ALL
    SELECT *
    FROM Archive.Table
    ) AS T
WHERE T.CreatedAt > @StartDate;

Для того, чтобы еще больше ускорить работу. Вы можете добавить ограничение в свою архивную таблицу, например:

ALTER TABLE Archive.Table
ADD CONSTRAINT CK_ArchiveTable_CreatedAt CHECK (DATEDIFF(DAY, CreatedAt, GETDATE()) < 45);

Это должно дать подсказку для SQL Server не запрашивать эту таблицу, если ваш @StartDate меньше 45 дней. Имейте в виду, что это можно переписать, используя DATEADD. (). Это может быть более эффективно.

person Evaldas Buinauskas    schedule 02.05.2017
comment
На самом деле я начал обдумывать логику вашего первого утверждения, просто в другой формулировке. Я также попробую ваши другие 2 предложения, но это ответ для меня. Спасибо. - person Vadzim Savenok; 02.05.2017
comment
@VadzimSavenok да, в условных операторах нет ничего плохого, но я предпочитаю красивый код. Дайте мне знать, если другие два решения сработали для вас. Мне любопытно. - person Evaldas Buinauskas; 02.05.2017