Linq2Sql GroupBy implementation
От: IT Россия linq2db.com
Дата: 21.08.09 03:42
Оценка:
Есть вопрос, который очень хочется обсудить с коллективным разумом.

Сначала преамбула.

Есть такой linq запрос:

var q =
    from ch in Childs
    group ch by ch.ParentID;

Вполне такой ничего себе запрос. В результате его выполнения будет выполнен SQL запрос, поднимающий сгруппированные записи, а затем будет выполнено по одному запросу для каждой группы, загружащему подгруппу. Примерно так:

SELECT [t0].[ParentID] AS [Key]
FROM [Child] AS [t0]
GROUP BY [t0].[ParentID]
GO

-- Region Parameters
DECLARE @x1 Int = 1
-- EndRegion
SELECT [t0].[ParentID], [t0].[ChildID]
FROM [Child] AS [t0]
WHERE ((@x1 IS NULL) AND ([t0].[ParentID] IS NULL)) OR ((@x1 IS NOT NULL) AND ([t0].[ParentID] IS NOT NULL) AND (@x1 = [t0].[ParentID]))
GO

-- Region Parameters
DECLARE @x1 Int = 2
-- EndRegion
SELECT [t0].[ParentID], [t0].[ChildID]
FROM [Child] AS [t0]
WHERE ((@x1 IS NULL) AND ([t0].[ParentID] IS NULL)) OR ((@x1 IS NOT NULL) AND ([t0].[ParentID] IS NOT NULL) AND (@x1 = [t0].[ParentID]))
GO

-- Region Parameters
DECLARE @x1 Int = 3
-- EndRegion
SELECT [t0].[ParentID], [t0].[ChildID]
FROM [Child] AS [t0]
WHERE ((@x1 IS NULL) AND ([t0].[ParentID] IS NULL)) OR ((@x1 IS NOT NULL) AND ([t0].[ParentID] IS NOT NULL) AND (@x1 = [t0].[ParentID]))
GO

-- Region Parameters
DECLARE @x1 Int = 4
-- EndRegion
SELECT [t0].[ParentID], [t0].[ChildID]
FROM [Child] AS [t0]
WHERE ((@x1 IS NULL) AND ([t0].[ParentID] IS NULL)) OR ((@x1 IS NOT NULL) AND ([t0].[ParentID] IS NOT NULL) AND (@x1 = [t0].[ParentID]))

Всё бы хорошо, но на каждую группу мы получим по одному запросу, что при приличном размере первого запроса может легко убить базу.

В принципе, сделать всё как есть, так же как и сделать всё по человечески двумя запросами, на данный момент не представляет особого труда. Но в последнем случае будет потеряна ленивость. Т.е. придётся результат первого да и скорее всего второго запроса закачивать в память полностью и уже потом отдаваться энумераторам. Что опять же при приличном размере первого запроса выльется в приличный объём памяти.

Собственно вопрос — как лучше поступить? Повторить реализацию MS или сделать более оптимальный для сервера БД, но затратный по памяти для клиента вариант?
Если нам не помогут, то мы тоже никого не пощадим.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.