Подтвердить что ты не робот

Как повысить производительность кластеризованного индекса

Я пытаюсь улучшить производительность в запросе, который работает очень медленно. Пройдя через План фактического исполнения; Я обнаружил, что Clustered Index Seek занимает 82%. Есть ли какой-либо способ улучшить производительность в поисках индекса? Ниже приведен образ проблемы Index Seek из плана выполнения, а также индекс и таблица, которые он использует.

alt text http://img340.imageshack.us/img340/1346/seek.png

Индекс

/****** Object:  Index [IX_Stu]    Script Date: 12/28/2009 11:11:43 ******/
CREATE CLUSTERED INDEX [IX_Stu] ON [dbo].[stu] 
(
 [StuKey] ASC
)WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]

Таблица (некоторые столбцы опущены для краткости):

CREATE TABLE [dbo].[stu](
 [StuCertKey] [int] IDENTITY(1,1) NOT NULL,
 [StuKey] [int] NULL
 CONSTRAINT [PK_Stu] PRIMARY KEY NONCLUSTERED 
(
 [StuCertKey] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
4b9b3361

Ответ 1

Я обобщаю здесь, но...

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

  • Обновите запрос, чтобы вернуть меньшее количество строк/столбцов, если это возможно;
  • Дефрагментировать или перестроить индекс;
  • Разделение индекса на несколько дисков/серверов.

Если он возвращает только 138 строк, а это медленнее... возможно, это блокируется каким-то другим процессом? Вы тестируете это отдельно или другие пользователи/процессы в Интернете одновременно? Или, может быть, это даже проблема с оборудованием, например, сбой диска.

Ответ 2

Поиск кластеризованного индекса происходит, когда используются некластеризованные индексы и не обязательно являются плохими.

Рассмотрим следующий запрос:

SELECT s.StuKey, s.Name, s.Address, s.City, s.State FROM stu s WHERE State='TX'

Если в StuKey есть только кластерный индекс, то у Sql Server только 1 опция, он должен проверять всю таблицу, ищущую строки, где State = "TX", и возвращать эти строки.

Если вы добавите некластеризованный индекс в State

CREATE INDEX IX_Stu_State on Stu (State)

Теперь у Sql-сервера есть новая опция. Он может выбрать поиск некластеризованного индекса, который будет создавать строки, где State = 'TX'. Однако, чтобы вернуть оставшиеся столбцы в SELECT, он должен искать эти столбцы, выполняя кластерный поиск индекса для каждой строки.

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

 CREATE INDEX IX_Stu_State2 on Stu (State) INCLUDE (name, address, city )

Этот индекс теперь содержит все столбцы, необходимые для ответа на указанный выше запрос. Запрос будет искать индекс, чтобы возвращать только строки, где State = 'TX', а дополнительные столбцы могут быть выведены из некластеризованного индекса, поэтому поиск кластерного индекса исчезает.

Ответ 3

Поиск кластеризованного диапазона индексов, который возвращает 138 строк, не является вашей проблемой.

Технически вы можете улучшить производительность поиска, сделав кластеризованный индекс более узким:

Оба могут иметь весьма драматическое влияние на время поиска по диапазону, поскольку они уменьшают IO и необходимость ударить физические чтения. Конечно, как обычно, результат будет зависеть от большого количества других факторов, например, какие столбцы вы проецируете (вытеснение проецируемого столбца в блок выделения BLOB может иметь негативные последствия для некоторых запросов). Как побочная заметка, обычно фрагментация будет иметь лишь незначительное влияние на такое короткое сканирование. Опять же, это зависит.

Но, как я уже сказал, я очень сомневаюсь, что это ваша настоящая проблема. Вы опубликовали только отдельные части плана и результаты собственного анализа. Истинная первопричина может зависеть совсем в другом месте.

Ответ 4

Мысли...

  • Почему кластер IX_Stu? Внутри SQL Server добавляет 4-байтовый "уникальный идентификатор" к неистинным кластеризованным индексам. Какое оправдание? Это также раздувает ваш ПК тоже

  • Каков фактический запрос, который вы используете?

  • Наконец, почему FILLFACTOR 80%?

Edit:

  • "Нормальный" FILLFACTOR будет 90%, но это правило только

  • Запрос соединения 11? Это, скорее всего, ваша проблема. Каковы ваши JOIN, WHERE и т.д.? Каков полный текст плана?

Ответ 5

Вы пробовали некоторое обслуживание по этому индексу? Как дефрагментировать это? Кажется действительно странным, что это дорого стоит (120.381). Индексный поиск - это самая быстрая операция индекса, не так долго. Вы можете отправить запрос?

Ответ 6

Что произойдет, если вы жестко определите критерии WHERE, например:

SELECT StuCertKey, StuKey FROM stu 
WHERE stuKey in (/* list 50 values of StuKey here */)

Если он все еще очень медленный, у вас есть внутренняя проблема. Если это быстрее, то индекс не является вашим узким местом, это JOINs, которые вы делаете, чтобы создать фильтр WHERE.

Обратите внимание, что SELECT * может быть очень медленным, если есть много больших столбцов, и особенно если есть BLOB.

Ответ 7

Некоторые общие рекомендации: когда я должен выполнять оптимизацию запросов, я начинаю с того, что считаю, что план выполнения должен быть.

Как только я решил, что, по моему мнению, должен быть план выполнения, я пытаюсь сделать фактический запрос подходящим для этого плана. Методы для этого различны для каждой СУБД и не обязательно переходят от одного к другому или даже иногда к различным версиям СУБД.

Следует иметь в виду, что СУБД может выполнять только одно соединение за раз: оно начинается с двух начальных таблиц, присоединяет их, а затем берет результат этой операции и присоединяет ее к следующей таблице. Цель каждого шага состоит в том, чтобы свести к минимуму количество строк в промежуточном результирующем наборе (точнее, чтобы свести к минимуму количество блоков, которые нужно читать для получения промежуточных результатов, но это обычно означает наименьшее количество строк).

Ответ 8

Проверьте статистическую статистику.

reCalculating статистика кластеризованного индекса решит проблему.

в моем случае, я искал 30 записей в 40M. в плане исполнения говорится, что он проходит через кластеризованный индекс, но он занял около 200 мс. и индекс не был дефрагментирован. после пересчета его статистики, это делается до 10 мс!

Ответ 9

Восстановить индекс и рассчитать статистику?

Единственный способ, с помощью которого я могу ускорить его, - это разбить таблицу, которая может быть или не быть возможной.