Как переписать простое условие SQL для повышения производительности

#sql #sql-server #tsql #where-clause

#sql #sql-сервер #tsql #where-предложение

Вопрос:

У меня есть простой запрос ниже, чтобы выбрать доступные активы из таблицы на основе их оформления заказа и ожидаемой даты возврата. Если проверка и ожидаемая дата возврата совпадают с @RentStartDate , а @RentEndDate затем я хочу выбрать его как UnavailableAsset . Пожалуйста, ознакомьтесь с моим запросом ниже

 set @RentStartDate = '2016-10-13';
set @RentEndDate = '2016-10-18';

SELECT AssetID as UnAvailableAsset
FROM agreementasset
WHERE (CheckOutDate >= @RentStartDate AND CheckOutDate <= @RentEndDate)
OR
(ExpectedReturnDate >= @RentStartDate AND ExpectedReturnDate <= @RentEndDate)
OR
(@RentStartDate >= CheckOutDate AND @RentEndDate <= ExpectedReturnDate);
 

Теперь я знаю, что этот запрос работает отлично, но я просто не уверен, есть ли лучший способ написать условия в where предложении.
Есть ли лучший способ упростить условия, чтобы сделать этот запрос более эффективным?

Спасибо

Комментарии:

1. Какой движок базы данных? Вы проверили план запроса, чтобы узнать, что он делает?

2. Определение таблицы, включая индексы и т.д.?

3. Хотя, скорее всего, это не дает лучшей производительности, но улучшает читаемость, вы могли бы заменить (CheckOutDate >= @RentStartDate AND CheckOutDate <= @RentEndDate) на CheckOutDate BETWEEN @RentStartDate AND @RentEndDate и (ExpectedReturnDate >= @RentStartDate AND ExpectedReturnDate <= @RentEndDate) на ExpectedReturnDate BETWEEN @RentStartDate AND @RentEndDate .

4. Добавлен sql-server тег на основе используемого синтаксиса

Ответ №1:

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

Запрос перекрытия должен выглядеть следующим образом:

 SELECT AssetID as UnAvailableAsset
FROM agreementasset
WHERE CheckOutDate <= @RentEndDate AND
      ExpectedReturnDate >= @RentStartDate;
 

Этот тип запросов может быть сложно оптимизировать (в большинстве баз данных). Вы можете начать с индекса на agreementasset(CheckOutDate, ExpectedReturnDate, AssetID) .

Комментарии:

1. Я уже пробовал этот запрос раньше. Он выбирает только тот ресурс, который имеет как checkout, так и expectedReturndate, попадающие в диапазон дат аренды. Что я имел в виду под перекрытием, так это то, что даже если проверка или ожидаемый возврат попадают в диапазон даты аренды, этот ресурс будет недоступен

2. Похоже, что индексирование — это правильный путь.

3. @Vibol. . . Внимательно прочитайте запрос. Это логика для любого перекрытия периодов времени.

Ответ №2:

Вы пробовали использовать BETWEEN ключевое слово?

 SELECT AssetID as UnAvailableAsset
FROM agreementasset
WHERE (CheckOutDate BETWEEN @RentStartDate AND @RentEndDate)
OR (ExpectedReturnDate BETWEEN @RentStartDate AND @RentEndDate)
 

Комментарии:

1. Вы забыли включить последнее OR (@RentStartDate >= CheckOutDate AND @RentEndDate <= ExpectedReturnDate) . Этот случай не распространяется на ваши предикаты. (По крайней мере, если у вас нет более глубокого понимания предполагаемой логики предикатов.)

Ответ №3:

Я не думаю, что вы можете упростить и не дублировать условия

 SELECT AssetID as UnAvailableAsset
FROM agreementasset
WHERE (@RentStartDate <= CheckOutDate       AND @RentEndDate >= CheckOutDate)
   OR (@RentStartDate >= CheckOutDate       AND @RentEndDate <= ExpectedReturnDate)
   OR (@RentStartDate <= ExpectedReturnDate AND @RentEndDate >= ExpectedReturnDate);