Этот вопрос является продолжением Этот вопрос
Решение, очистка кэша плана выполнения, казалось, работало в то время, но я снова и снова сталкивался с одной и той же проблемой, и очистка кэша больше не помогает. Здесь должна быть более глубокая проблема.
Я обнаружил, что если я удаляю .Distinct () из запроса, он возвращает строки (с дубликатами) примерно через 2 секунды. Однако, с .Distinct () это может занять до 4 минут. В таблицах много строк, а некоторые из полей предложения where не имеют индексов. Однако количество возвращаемых записей довольно мало (максимум несколько десятков).
Неясность в том, что если я получаю SQL, сгенерированный запросом Linq, через Linqpad, то выполняю этот код как SQL или в SQL Management Studio (включая DISTINCT), он выполняется примерно за 3 секунды.
В чем разница между запросом Linq и выполненным SQL?
У меня есть краткосрочный обходной путь, и он возвращает набор без .Distinct () в виде списка, а затем использует .Distinct в списке, это занимает около 2 секунд. Однако мне не нравится работать с SQL Server на веб-сервере.
Я хочу понять, ПОЧЕМУ Distinct на 2 порядка медленнее в Linq, но не в SQL.
UPDATE:
При выполнении кода через Linq профилировщик sql показывает этот код, который в основном является идентичным запросом.
sp_executesql N'SELECT DISTINCT [t5].[AccountGroupID], [t5].[AccountGroup]
AS [AccountGroup1]
FROM [dbo].[TransmittalDetail] AS [t0]
INNER JOIN [dbo].[TransmittalHeader] AS [t1] ON [t1].[TransmittalHeaderID] =
[t0].[TransmittalHeaderID]
INNER JOIN [dbo].[LineItem] AS [t2] ON [t2].[LineItemID] = [t0].[LineItemID]
LEFT OUTER JOIN [dbo].[AccountType] AS [t3] ON [t3].[AccountTypeID] =
[t2].[AccountTypeID]
LEFT OUTER JOIN [dbo].[AccountCategory] AS [t4] ON [t4].[AccountCategoryID] =
[t3].[AccountCategoryID]
LEFT OUTER JOIN [dbo].[AccountGroup] AS [t5] ON [t5].[AccountGroupID] =
[t4].[AccountGroupID]
LEFT OUTER JOIN [dbo].[AccountSummary] AS [t6] ON [t6].[AccountSummaryID] =
[t5].[AccountSummaryID]
WHERE ([t1].[TransmittalEntityID] = @p0) AND ([t1].[DateRangeBeginTimeID] = @p1) AND
([t1].[ScenarioID] = @p2) AND ([t6].[AccountSummaryID] = @p3)',N'@p0 int,@p1 int,
@p2 int,@p3 int',@p0=196,@p1=20100101,@p2=2,@p3=0
UPDATE:
Единственное различие между запросами состоит в том, что Linq выполняет его с sp_executesql, а SSMS - нет, в противном случае запрос идентичен.
UPDATE:
Я пробовал разные уровни изоляции транзакций, но безрезультатно. Я также установил ARITHABORT, чтобы попытаться принудительно перекомпилировать его при выполнении, и без разницы.