Каков эффективный метод разбивки на страницы с очень большими наборами результатов в SQL Server 2005? - PullRequest
6 голосов
/ 04 октября 2008

РЕДАКТИРОВАТЬ: Я все еще жду больше ответов. Спасибо!

В SQL 2000 дней я использовал метод временной таблицы, где вы создаете временную таблицу с новым столбцом идентификаторов и первичным ключом, а затем выбираете, где столбец идентификаторов находится между A и B.

Когда SQL 2005 появился, я узнал о Row_Number() и использую его с тех пор ...

Но теперь я обнаружил серьезную проблему с производительностью Row_Number(). Он работает очень хорошо, когда вы работаете с не столь гигантскими наборами результатов и сортируете по столбцу идентификаторов. Однако он работает очень плохо , когда вы работаете с большими наборами результатов , такими как более 10000 записей и , сортирующими его по столбцу без идентификатора . Row_Number() работает плохо, даже если вы сортируете по столбцу идентификаторов, если набор результатов превышает 250 000 записей. Для меня это дошло до того, что выдает ошибку: « команда timeout! »

Что вы используете для разбивки большого набора результатов в SQL 2005? В этом случае метод временных таблиц еще лучше? Я не уверен, что этот метод с использованием временной таблицы с SET ROWCOUNT будет работать лучше ... Но некоторые говорят, что есть проблема с неправильным номером строки, если у вас есть первичный ключ из нескольких столбцов.

В моем случае мне нужно иметь возможность сортировать результаты по столбцу типа даты ... для моего рабочего веб-приложения.

Дайте мне знать, что вы используете для высокопроизводительной нумерации страниц в SQL 2005 . И я также хотел бы знать умный способ создания индексов. Я подозреваю, что выбор правильных первичных ключей и / или индексов (кластеризованных / некластеризованных) сыграет здесь большую роль.

Заранее спасибо.

P.S. Кто-нибудь знает, что использует stackoverflow?

РЕДАКТИРОВАТЬ: Моя выглядит примерно так ...

SELECT postID, postTitle, postDate
FROM
   (SELECT postID, postTitle, postDate, 
         ROW_NUMBER() OVER(ORDER BY postDate DESC, postID DESC) as RowNum
    FROM MyTable
   ) as DerivedMyTable
WHERE RowNum BETWEEN @startRowIndex AND (@startRowIndex + @maximumRows) - 1

postID: Int, Identity (автоинкремент), первичный ключ

postDate: DateTime

РЕДАКТИРОВАТЬ: Все используют Row_Number ()?

Ответы [ 2 ]

7 голосов
/ 04 октября 2008

Метод row_number () должен быть быстрым. Я видел хорошие результаты для 100 000 строк.

Используете ли вы row_number (), похожее на следующее:

SELECT column_list
FROM
   (SELECT column_list
         ROW_NUMBER() OVER(ORDER BY OrderByColumnName) as RowNum
    FROM MyTable m
   ) as DerivedTableName
WHERE RowNum BETWEEN @startRowIndex AND (@startRowIndex + @maximumRows) - 1

... а у вас есть индекс покрытия для column_list и / или индекс для столбца 'OrderByColumnName'?

0 голосов
/ 21 октября 2008

Ну, для вашего примера запроса ROW_COUNT должен быть довольно быстрым с тысячами строк, если у вас есть индекс в поле PostDate. Если вы этого не сделаете, серверу необходимо выполнить полное сканирование кластерного индекса на вашем ПК, практически загрузить каждую страницу, извлечь поле PostDate, отсортировать его, определить строки, которые нужно извлечь для результирующего набора, и снова извлечь эти строки. Это своего рода создание временного индекса снова и снова (вы можете увидеть спул таблицы / индекса в простом виде). ​​

Не удивительно, что вы получаете тайм-ауты.

Мое предложение: установить индекс для PostDate DESC, это то, что ROW_NUMBER будет проходить - (ORDER BY PostDate DESC, ...)

Что касается статьи, на которую вы ссылаетесь - в прошлом я довольно много разбирался с SQL Server 2000 и разбирался с ним без использования ROW_COUNT, а подход, использованный в этой статье, является наиболее эффективным. Это не работает при любых обстоятельствах (вам нужны уникальные или почти уникальные значения). Обзор некоторых других методов: здесь .

.

...