Вы можете продемонстрировать, выполняются ли два рассматриваемых запроса одинаково в SQL Server, просмотрев планы выполнения.Возьмите следующий тестовый код (я использовал SQL Server 2008):
CREATE TABLE #TABLES ([ID] INT IDENTITY, [Name] VARCHAR(30))
INSERT INTO #TABLES VALUES('A')
INSERT INTO #TABLES VALUES('A')
INSERT INTO #TABLES VALUES('B')
INSERT INTO #TABLES VALUES('C')
INSERT INTO #TABLES VALUES('D')
SELECT NAME
FROM #TABLES
WHERE [Name] <> 'D'
GROUP BY NAME
HAVING COUNT(*) > 1
SELECT [t1].[NAME]
FROM (
SELECT COUNT(*) AS [value], [t0].[NAME]
FROM [#TABLES] AS [t0]
WHERE [t0].[NAME] <> 'D'
GROUP BY [t0].[NAME]
) AS [t1]
WHERE [t1].[value] > 1
DROP TABLE #TABLES
Выполнение этих запросов из SQL Query Analyzer с выбранным в меню «Запрос» «Включить фактический план выполнения» даст следующий вывод:
В этом случае, поскольку сгенерированные планы запросов точно такие же, очевидно, что не должно быть никакой разницы в производительности между вашим SQL и SQL, сгенерированным из вашего оператора LINQ.
В качестве дополнительного примечания, к сожалению, я не смог найти никакой документации о том, почему LinqToSql не использует HAVING, или если использование HAVING по сравнению с использованием дополнительного выбора приводит к увеличению производительности тем или иным способом,Если бы мне пришлось угадывать, я бы сказал, что оптимизатор запросов в SQL Server внутренне превращает эти операторы в один и тот же запрос до их выполнения, поэтому планы выполнения идентичны для обоих операторов.Является ли мое предыдущее утверждение верным, я бы сказал, что если у вас есть какие-либо сомнения, просто проверьте планы выполнения для вашей версии SQL по сравнению с версией LinqToSql.Если они одинаковые, то вам не о чем беспокоиться по поводу производительности.Если ваша версия SQL намного эффективнее, вы всегда можете написать хранимую процедуру и просто вызвать хранимую процедуру с помощью LinqToSql.