SQL для выбора кластера записей из огромной таблицы с оптимальным SQL

#sql-server-2005 #tsql

#sql-server-2005 #tsql

Вопрос:

Я пытаюсь разбить на страницы, используя MS SQL Server 2005 в одном из моих приложений ASP net. Для извлечения 10 записей из таблицы employee я запускаю следующий SQL.

 ;WITH CTE AS (
                SELECT EmployeeID,
                       [Name],
                       ROW_NUMBER() OVER(ORDER BY EmployeeID ASC) AS RowNo
                FROM   Employee
            ) SELECT *
              FROM   CTE WHERE RowNo BETWEEN 11 AND 20  
  

Проблема в том, что в моей таблице employee содержится 100 тысяч записей, и поскольку я выполняю приведенный выше запрос, это занимает много времени. Я видел в MySQL, что есть фраза LIMIT для ограничения количества выбранных записей.

Пожалуйста, помогите мне получить определенное количество записей записей без использования общего табличного выражения и без выполнения запроса, подобного приведенному выше. Я хотел бы знать, есть ли лучший способ, чем этот.

Заранее спасибо за ваше время и помощь.

Комментарии:

1. Какие индексы у вас есть в вашей Employee таблице? В каких диапазонах проблема? Даже BETWEEN 11 AND 20 медленно или у вас возникает проблема с гораздо большими числами?

2. @MartinSmith, идентификатор сотрудника является моим первичным ключом и представляет собой целое число. Даже для извлечения от 11 до 20 записей я сталкиваюсь с проблемой производительности. Проблема становится намного больше, когда я пытаюсь получить более высокие числа. Таблица Employee имеет много внешних ключей (не менее 6).

3. Создание дублирующего некластеризованного индекса EmployeeId и перезапись запроса помогут с более высокими страницами, но, возможно, у вас проблема с блокировкой, поскольку для более низких страниц запрос в вашем вопросе должен быть вполне разумным.

Ответ №1:

Я попробовал ваш запрос для таблицы с 150.000 строк, я попробовал для столбца с индексом и столбца без индекса. Время выполнения обоих составляло менее 1 секунды. Я полагаю, у вас другая проблема.

Поскольку я полагаю, что ваша проблема заключается в другом, я предлагаю вам попробовать это:

 ;WITH CTE AS ( 
            SELECT EmployeeID, 
                   [Name], 
                   ROW_NUMBER() OVER(ORDER BY EmployeeID ASC) AS RowNo 
            FROM   Employee WITH (NOLOCK)
        ) SELECT * 
          FROM   CTE WHERE RowNo BETWEEN 11 AND 20