Необычная сортировка: какие индексы нужны?
От: Слава  
Дата: 06.10.20 15:24
Оценка:
Есть таблица в MS SQL Express, у неё есть минимум три поля:

1) username
2) state
3) date

Нужно сделать постраничную выборку (размер страницы: 20 записей) с фильтром по username, некое значение state вынести в начало выборки и затем отсортировать всё имеющееся по date в порядке убывания, то есть самые больше даты идут в начале.

Я использую linq2db.
  Код C#, linq2db
var res = await c.GetTable<Mytable>().
          Where(x=>x.Username == username).
          OrderByDescending(x=>x.State == state).
          ThenByDescending(x=>x.Date).
          Skip(startFromIndex ?? 0).Take(20).
          Select(r=>
               new MyRecord
               {
                   Rating = Math.Round(r.Rating, 2),
                   City = r.City,
                   State = r.State,
                   FirstName = r.FirstName,
                   LastName = r.LastName,
                   Description= r.Description,
                   Date = r.Date,
               }
                    ).
          ToListAsync();
  Сгенерированный код sql
DECLARE @username NVarChar(100) -- String
SET     @username = N'XXXXXXXXX'
DECLARE @state_2 NVarChar(2) -- String
SET     @state_2 = N'KY'
DECLARE @skip Int -- Int32
SET     @skip = 900
DECLARE @take Int -- Int32
SET     @take = 20

SELECT
    [x].[rating],
    [x].[city],
    [x].[state],
    [x].[firstName],
    [x].[lastName],
    [x].[description],
    [x].[date]
FROM
    [dbo].[mytable] [x]
WHERE
    [x].[username] = @username 
ORDER BY
    IIF([x].[state] = @state_2, 1, IIF((NOT ([x].[state] = @state_2)), 0, NULL)) DESC,
    [x].[date] DESC
OFFSET @skip ROWS FETCH NEXT @take ROWS ONLY

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