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

StackOverflow https://stackoverflow.com/questions/1971045

Вопрос

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

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]
Это было полезно?

Решение

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

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

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

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

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

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

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

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

Если на Stukey есть только кластерный индекс, то SQL Server имеет только 1 опцию, он должен отсканировать всю таблицу в поисках строк, где состояние = "tx 'и вернуть эти строки.

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

CREATE INDEX IX_Stu_State on Stu (State)

Теперь SQL Server имеет новую опцию. Он может выбрать поиск, используя не кластеризованный индекс, который будет создавать строки, где состояние = 'tx'. Однако, чтобы заставить оставшиеся столбцы вернуться в выборе, он должен искать эти столбцы, выполнив кластерный индекс, ища для каждой строки.

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

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

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

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

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

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

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

Мысли...

  • Почему IX_STU кластер? Внутренне, SQL Server добавляет 4-байт «уникальный» в не одноразовые кластерные индексы. Что такое оправдание? Это также раздувает ваш PK

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

  • Наконец, зачем филфактор 80%?

Редактировать:

  • «Нормальный» филфактор составит 90%, но это только практическое правило

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

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

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

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

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

Что произойдет, если вы жестко ковроваете свой КУДА Критерии, как это:

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

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

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

Проверьте статиктику индекса.

По мнению статистики кластера-индекса решит проблему.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top