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

Я пытаюсь повысить производительность запроса, который выполняется очень медленно. После прохождения Фактический План Выполнения; Я нашел, что a Кластерный Индекс Искать занимал 82%. Есть ли способ для меня улучшить производительность на Искать? Ниже приведен образ проблемы Искать из плана выполнения, а также индекса и таблицы, используя.

alt-текст 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]

9 ответов


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

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

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

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


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

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

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

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

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

CREATE INDEX IX_Stu_State on Stu (State)

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

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

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

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


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

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

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

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


мысли...

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

  • каков фактический запрос, который вы выполняете?

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

Edit:

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

  • в 11 Join запрос? Скорее всего, это ваша проблема. Каковы ваши присоединяется, где п. и т. д.? Что такое полнотекстовый план?


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


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

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

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


что произойдет, если вы жесткий код здесь критерии, как это:

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

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

отметим, что SELECT * может быть очень медленным, если есть много больших колонн, и особенно, если есть капли.


Регистрация статистика индекса.

пересчет статистики кластеризованных индексов решит проблему.

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


перестроить индекс, и посчитать статистику?

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