Как выбрать большое количество записей в SQL SERVER

Я пытаюсь выбрать более 80 000 записей в SQL Server в таблице с миллионами записей. Проблема в том, что у меня правильный индекс, но для возврата набора записей требуется более 15 минут.

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

Любая помощь для более быстрого способа реализации?

добавлять дополнительную информацию, редактируя вопрос, а не размещая ответы; порядок ответов будет меняться со временем по мере накопления голосов

Steven A. Lowe 19.12.2008 18:08
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
7 046
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Есть несколько вариантов. Обычные приемы настройки БД (в которых я не эксперт). Можно ли за кулисами извлечь подмножество данных, которые вам нужны, в меньшую таблицу?

Он определенно использует индекс? Это кластерный индекс? Проверьте план выполнения. Вы также можете захотеть перестроить индекс.

В противном случае опубликуйте запрос, определение таблицы и индексы.

Это также может быть ограничение вашей конфигурации 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. Однако для этого требуются уникальные значения в отсортированном столбце.

liggett78 19.12.2008 20:02

@jmpena: извините, план выполнения требует 2% чтения с закладки и 98% сканирования индекса

Думаю, вы здесь ответили на свой вопрос. «98% сканирование индекса». Сканирование индекса просто означает, что SQL обнаружил индекс, который май помогает повысить производительность, выбранный на основе статистики. В зависимости от индекса операция может быть такой же плохой, как и сканирование самой таблицы.

Если вы правильно настроили индекс / запрос, вы должны увидеть поиск по индексу.

Можете рассказать, какие индексы есть в таблице? (sp_help {tablename})

Другие вопросы по теме