Представьте себе, что у нас есть две таблицы следующим образом:SQL Server РЕГИСТРИРУЙТЕСЬ с дополнительными значениями NULL
Trades
(
TradeRef INT NOT NULL,
TradeStatus INT NOT NULL,
Broker INT NOT NULL,
Country VARCHAR(3) NOT NULL
)
CTMBroker
(
Broker INT NOT NULL,
Country VARCHAR(3) NULL
)
(Они были упрощены для целей данного примера). Теперь, если мы хотим, чтобы присоединиться к этим две таблицы по колонке Broker и если страна существует в таблице CTMBroker по стране, мы имеем следующие два варианта:
SELECT T.TradeRef,T.TradeStatus
FROM Trades AS T
JOIN CTMBroker AS B ON B.Broker=T.Broker AND ISNULL(B.Country, T.Country) = T.Country
или
SELECT T.TradeRef,T.TradeStatus
FROM Trades AS T
JOIN CTMBroker AS B ON B.Broker=T.Broker AND (B.COUNTRY=T.Country OR B.Country IS NULL)
Они оба логически эквивалентны, однако в этом конкретном случае для нашей базы данных (SQL Server 2008, SP1) для этих двух запросов создаются два разных плана выполнения, причем вторая версия значительно превосходит первую версию с точки зрения как времени, так и логического считывания ,
Мой вопрос в самом деле заключается в следующем: как правило, было бы предпочтительнее (1), или это просто произойдет с использованием некоторой конкретной идиосинкразии оптимизатора в SP1 2008 года (это может поэтому измениться с будущим версии SQL Server).
+1 Вы никогда не хотите использовать какую-либо функцию или выражение на «левой» стороне условия WHERE. Это не позволяет использовать индексы, и это вызывает полное сканирование таблицы - в QA, включите демонстрационный план, и вы его легко увидите; если вы видите сканирование таблиц где угодно - ничего хорошего, если только это очень маленькая таблица – IMHO