Используя Linqpad, как предложено, и подключаясь к моей базе данных разработчика (после добавления значительного количества фиктивных данных) - я ответил на этот вопрос со следующими выводами:
Использование внешнего соединения привело к следующему SQL:
SELECT [t0].*
FROM [Foo] AS [t0]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t1].[FooId]
FROM [Bar] AS [t1])
AS [t2] ON [t0].[Id] = [t2].[FooId]
WHERE (NOT ([t0].[SomeBool] = 1))
AND ([t0].[SomeDate] IS NOT NULL)
AND (NOT ([t0].[SomeOtherDate] IS NOT NULL))
AND ([t2].[test] IS NULL)
Использование контекстного вызова с предикатом в условии, где предложение генерирует следующее SQL:
SELECT [t0].*
FROM [Foo] AS [t0]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM [Bar] AS [t1]
WHERE [t1].[FooId] = [t0].[Id])))
AND (NOT ([t0].[SomeBool] = 1))
AND ([t0].[SomeDate] IS NOT NULL)
AND ([t0].[SomeOtherDate] IS NULL)
- Время выполнения внешнего соединения: 0,681 с
- Предикат в таблице (контекст): 1,068 с
Я не могу с уверенностью объяснить, почему, но, как я подозревал, запрос, использующий внешнее соединение, значительно быстрее (157%). Я предполагаю, что он выполняет два действующих запроса вместо одного; один на Foo, а затем выполняет запрос на Bar в предложении where, тогда как внешнее соединение выполняет один запрос на предопределенные параметры.