Вы предполагаете, что если алгебраически возможно замкнуть накоротко, то оно должно замкнуть накоротко.Но это исключает преимущества параллелизма, особенно при работе со многими строками, а не с одним скалярным выражением (например, в C) .
Чтобы максимизировать параллельные операции, план выполнения может бытьгенерируется таким образом, что короткое замыкание не дает никакой пользы.Вот почему SQL declarative
, а не imperative
;Вы объявляете проблему, а затем SQL Server создает план для ее решения. (императивные языки выполняют решение, которое вы даете.) - В SQL
вы не можете контролировать порядок выполняемых операций, просто изменяя порядок своих выражений.
Один вариант:попытка force использовать вместо этого все три выражения в одном выражении CASE
, поскольку это линейная скалярная операция.
1 = CASE WHEN b.BookingID = TRY_CONVERT(int, @SearchByParam) THEN 1
WHEN c.CustomerName like '%'+ @SearchByParam +'%' THEN 1
WHEN c.VehicleRegNo like '%'+ @SearchByParam +'%' THEN 1 END
Это, однако, резко ограничивает возможности планировщика, и вы можете обнаружить, что производительность снижается.
РЕДАКТИРОВАТЬ:
Прочитав комментарии, добавленные с тех пор, как я начал писать этот ответ, я думаю, что вы неправильно поняли SQL.Это не вопрос короткого замыкания.В SQL предложение WHERE
применяется к каждой входной строке независимо от всех других строк.
Например, следующий код возвращает все строки, где myfield
либо 'x'
, либо 'y'
.Он не возвращает все строки, в которых они 'x'
, и собирается искать 'y'
, только если вхождения 'x'
не найдены ...
WHERE myfield = 'x' OR myfield = 'y'
-- Which is the same as...
WHERE myfield IN ( 'x', 'y' )
В вашем случае вы, похоже, пытаетесь реализовать условия динамического поиска.Из них есть много плохих способов сделать это, и только несколько хороших способов сделать это ...
Упрощенный способ "ничего хорошего" был бы таким ...
DECLARE @SearchByParam VARCHAR(20) = '3',
@SearchByType INT = 1
SELECT
<blah>
WHERE
(@SearchByType = 1 AND b.BookingID= TRY_CONVERT(int, @SearchByParam))
OR (@SearchByTYpe = 2 AND c.CustomerName like '%'+ @SearchByParam +'%' )
OR (@SearchByType = 3 AND c.VehicleRegNo like '%'+ @SearchByParam +'%' )
Это "не хорошо", потому что если вы хотите выполнить поиск по BookingID
, вы уничтожили способность оптимизатора строитьзапрос по любому индексу.
На самом деле вам будет лучше с тремя запросами, каждый из которых соответствует различным критериям поиска.Или, возможно, динамический SQL, где вы добавляете необходимое условие WHERE
в строку запроса, а затем выполняете эту строку.
Для небольших объемов данных приведенный выше пример может вам помочь.Для больших объемов данных либо используйте несколько запросов, выделенных для каждого варианта использования, либо прочитайте это (очень подробно, но очень информативно) статья: http://www.sommarskog.se/dyn-search.html