I have a fairly simple sales query that can potentially return over 100k rows in any given request. The (simplified) linq query is as follows:
var query = from adi in _repo.AccountingDocumentItems
select new Sales
{
TotalInclusive = adi.TotalInclusive,
Employees = adi.Employees.Select(x => x.FirstName + " " + x.LastName)
};
Because a sale can be assigned to multiple employees, and I need this info - I'm pulling a IEnumerable string of names here so that I can later join them with a comma.
The resulting query looks like the below, note the last line where it orders by AccountingDocumentItemId - this only happens when I pull the IEnumerable:
SELECT
[Project1].[AccountingDocumentItemId] AS [AccountingDocumentItemId],
[Project1].[C1] AS [C1],
[Project1].[TotalInclusive] AS [TotalInclusive],
[Project1].[C3] AS [C2],
[Project1].[C2] AS [C3]
FROM ( SELECT
[Extent1].[AccountingDocumentItemId] AS [AccountingDocumentItemId],
[Extent1].[TotalInclusive] AS [TotalInclusive],
1 AS [C1],
CASE WHEN ([Join1].[AccountingDocumentItemId] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE [Join1].[FirstName] + N' ' + [Join1].[LastName] END AS [C2],
CASE WHEN ([Join1].[AccountingDocumentItemId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C3]
FROM [dbo].[AccountingDocumentItems] AS [Extent1]
LEFT OUTER JOIN (SELECT [Extent2].[AccountingDocumentItemId] AS [AccountingDocumentItemId], [Extent3].[FirstName] AS [FirstName], [Extent3].[LastName] AS [LastName]
FROM [dbo].[AccountingDocumentItemEmployees] AS [Extent2]
INNER JOIN [dbo].[Employees] AS [Extent3] ON [Extent3].[EmployeeId] = [Extent2].[EmployeeId] ) AS [Join1] ON [Extent1].[AccountingDocumentItemId] = [Join1].[AccountingDocumentItemId]
) AS [Project1]
ORDER BY [Project1].[AccountingDocumentItemId] ASC, [Project1].[C3] ASC
Generally this is fine, it executes quite well but the sort in that query gets worse the more columns I attempt to retrieve. So the issue is that SQL Server is having to perform a very expensive Sort operation, especially when the number of rows starts hitting over 100k.
I'd like to avoid doing this, but I can't see any other way to retrieve the employees per sale. I did try grouping by AccountingDocumentItemId and then grouping in C# itself, but the performance to do this on 100k+ rows is terrible.
How can I restructure this query to avoid the sort, but still return an IEnumerable of employee names?