Я пытаюсь выбрать более 80 000 записей в SQL Server в таблице с миллионами записей. Проблема в том, что у меня правильный индекс, но для возврата набора записей требуется более 15 минут.
Я использую MS SQL Server 2000, я нашел метод разбивки на страницы с использованием хранимых процедур, но он использует временную таблицу, в которую мне нужно вставить весь набор результатов, а затем выбрать количество записей, которые я собираюсь показать на странице. Этот метод занимает слишком много времени.
Любая помощь для более быстрого способа реализации?





Есть несколько вариантов. Обычные приемы настройки БД (в которых я не эксперт). Можно ли за кулисами извлечь подмножество данных, которые вам нужны, в меньшую таблицу?
Он определенно использует индекс? Это кластерный индекс? Проверьте план выполнения. Вы также можете захотеть перестроить индекс.
В противном случае опубликуйте запрос, определение таблицы и индексы.
Это также может быть ограничение вашей конфигурации SQL (количество используемой оперативной памяти и т. д.) Или вашего оборудования. Это один диск или RAID? Если в RAID один из дисков отказал, что привело к фоновой перестройке?
Вам придется отредактировать это, чтобы реализовать ваши входные параметры для пользовательских параметров фильтрации и сортировки, но будет применяться общий принцип. Я использовал эту технику с SQL 2000 в период 2000/2001 годов с таблицей записей 90M, чтобы обеспечить быструю подкачку страниц для 150- 200 тыс. Наборов результатов. Поскольку во временной таблице находится только ключ, это очень узкая, очень маленькая временная таблица, и производительность высокая (и для этого шага требуется только прочитать индекс основной таблицы, а не саму таблицу). , при фактическом создании данных из основной таблицы для фактического (меньшего) набора результатов возврата (только строки @PageSize) запрос должен прочитать только очень мало записей ...
Create Procedure GetPagedData
@Page Integer = 1,
@PageSize Integer = 100,
@UsersFilteringCOnditions,
@UsersSortOptions
As
Set NoCount On
Declare @Start Integer,
Declare @End Integer
Declare @NumRecs Integer
-- Declare a temp table variable to hold all the pk values...
Declare @Keys Table (rowNum integer Identity Primary Key NotNull,
keyVal Integer Not Null)
-- Insert all the Primary Keys into the temp table variable...
Insert @keys(keyVal)
Select PrimaryKey From MyMillionRowTable
Where UsersFilterConditionsAreTrue
Order By UsersSortOptions
-- Then, select from your big table only the data
-- from the rows for the page the user wants
Select @NumRecs = Count(*) From Keys
Set @End = @Page * @PageSize
Set @Start = @End + 1 - @PageSize
Select {Insert ColumnListHere}
From MyMillionRowTable T
Join @Keys K On K.KeyVal = T.PrimaryKey
Where K.rowNum Between @Start And @End
Вам не нужно вставлять ВСЕ ключи во временную таблицу, только строки @Page * @PageSize. Есть еще один способ разбиения на страницы, который еще быстрее - см. RowCount в этой статье: codeproject.com/KB/aspnet/PagingLarge.aspx. Однако для этого требуются уникальные значения в отсортированном столбце.
@jmpena: извините, план выполнения требует 2% чтения с закладки и 98% сканирования индекса
Думаю, вы здесь ответили на свой вопрос. «98% сканирование индекса». Сканирование индекса просто означает, что SQL обнаружил индекс, который май помогает повысить производительность, выбранный на основе статистики. В зависимости от индекса операция может быть такой же плохой, как и сканирование самой таблицы.
Если вы правильно настроили индекс / запрос, вы должны увидеть поиск по индексу.
Можете рассказать, какие индексы есть в таблице? (sp_help {tablename})
добавлять дополнительную информацию, редактируя вопрос, а не размещая ответы; порядок ответов будет меняться со временем по мере накопления голосов