Я привык получать преимущества от функции ROW_NUMBER в сценариях MS SQL Server с версии 2005 года. Но я заметил, что существует большой недостаток производительности при запросе больших таблиц с использованием этой функции.
Представьте себе таблицу с четырьмя столбцами (настоящая таблица из внешней базы данных имеет больше столбцов, но я использовал только их, чтобы не усложнять пример):
DECLARE TABLE StockItems (
Id int PRIMARY KEY IDENTITY(1,1),
StockNumber nvarchar(max),
Name nvarchar(max),
[Description] nvarchar(max))
Я написал процедуру для запроса этой таблицы, заполненной более чем 200 000 строк, со следующими параметрами:
- @SortExpression — имя столбца, по которому я хочу сортировать
- @SortDirection - битовая информация (0=по возрастанию, 1=по убыванию)
- @startRowIndex - нулевой индекс, по которому я хочу получить строки
- @maximumRows — количество извлекаемых строк
Запрос:
SELECT sortedItems.Id
,si.StockNumber
,si.Name
,si.Description
FROM (SELECT s.Id
,CASE WHEN @SortDirection=1 THEN
CASE
WHEN CHARINDEX('Name',@SortExpression)=1 THEN
ROW_NUMBER() OVER (ORDER by s.Name DESC)
WHEN CHARINDEX('StockNumber',@SortExpression)=1 THEN
ROW_NUMBER() OVER (ORDER by s.StockNumber DESC)
ELSE ROW_NUMBER() OVER (ORDER by s.StockNumber DESC)
END
ELSE
CASE
WHEN CHARINDEX('Name',@SortExpression)=1 THEN
ROW_NUMBER() OVER (ORDER by s.Name ASC)
WHEN CHARINDEX('StockNumber',@SortExpression)=1 THEN
ROW_NUMBER() OVER (ORDER by s.StockNumber ASC)
ELSE ROW_NUMBER() OVER (ORDER by s.StockNumber ASC)
END
END AS RowNo
FROM stockItems s
) as sortedItems
INNER JOIN StockItems si ON sortedItems.Id=si.Id
ORDER BY sortedItems.RowNo
В ситуации, когда количество строк быстро растет, ROW_NUMBER становится неэффективным, т.к. должен сортировать все строки.
Пожалуйста, не могли бы вы помочь мне избежать этого недостатка производительности и ускорить запрос?