На производительность влияет, когда EF использует ROW_NUMBER () для упорядочивания и подкачки - PullRequest
1 голос
/ 30 октября 2019

У меня есть представление Entity в моей базе данных и класс Entity в коде, который представляет представление. Чтобы получить результат для определенной страницы, я делаю это:

var result = await dbContext.Entity
    .OrderByDescending(e => e.CreatedOn)
    .ThenByDescending(e => e.Id)
    .Skip((currentPage - 1) * itemsPerPage)
    .Take(itemsPerPage)
    .ToListAsync();

Для первой страницы из 50 элементов (currentPage = 1, itemsPerPage = 50) EF генерирует следующее:

SELECT 
    [Extent1].[OrderId] AS [Id], 
    [Extent1].[Number] AS [CreatedOn], 
    ...
    FROM [dbo].[Entity] AS [Extent1]
    ORDER BY row_number() OVER (ORDER BY [Extent1].[CreatedOn] DESC, [Extent1].[Id] DESC)
    OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY 

Проблема в том, что запрос выполняется довольно долго. И именно поэтому я попытался без row_number (), и это было быстрее, и я получил те же результаты:

SELECT 
    [Extent1].[OrderId] AS [Id], 
    [Extent1].[Number] AS [CreatedOn], 
    ...
    FROM [dbo].[Entity] AS [Extent1]
    ORDER BY [Extent1].[CreatedOn] DESC, [Extent1].[Id] DESC
    OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY 

Итак, мои вопросы:
1) Почему row_number () используется здесь в целом?
2) Есть ли какая-либо причина, по которой EF не использует его в этом запросе?

ОБНОВЛЕНИЕ: Добавление кластеризованного индекса в таблицу, представление которой используется, помогло повысить производительность. Спасибо!

1 Ответ

0 голосов
/ 30 октября 2019

Проверьте, быстрее ли это:

var result = await dbContext.Entity
    .OrderByDescending(e => e.CreatedOn)
    .ThenByDescending(e => e.Id)
    .Select((x,i) => new {index = i, item = x})
    .GroupBy(x => x.index / itemsPerPage)
    .Select(x => x.Select(y => y.item).ToList())
    .ToListAsync();
...