Каковы последствия преобразования индексов кучи в кластерные индексы на SQL Server? - PullRequest
5 голосов
/ 14 декабря 2010

Недавно я получил совет, что я должен преобразовать все наши таблицы из индексов кучи, чтобы каждая таблица имела кластеризованный индекс. Каковы последствия продолжения этой стратегии? Например. важнее ли регулярно проводить реорганизацию базы данных? datagrowth? опасность действительно медленных вставок? Опасность дефрагментации страницы, если ПК является GUID? Заметное увеличение скорости моего приложения? Какие у вас впечатления?

Чтобы послужить вдохновением для получения хороших ответов, вот некоторые «факты», которые я нашел в других темах здесь на stackoverflow

  1. Почти наверняка нужно создать кластерный индекс для каждой таблицы в вашей базе данных. Если таблицы нет. Производительность большинства распространенных запросов лучше.
  2. Кластерные индексы не всегда плохи для GUID ... все зависит от потребностей вашего приложения. Скорость INSERT пострадает, но скорость SELECT будет улучшена.
  3. Проблема с кластеризованными индексами в поле GUID заключается в том, что GUID являются случайными, поэтому при вставке новой записи значительную часть данных на диске необходимо переместить, чтобы вставить записи в середину таблицы.
  4. Кластерный индекс по GUID подходит для ситуаций, когда GUID имеет значение и повышает производительность, размещая связанные данные близко друг к другу http://randommadness.blogspot.com/2008/07/guids-and-clustered-indexes.html
  5. Кластеризация не влияет на скорость поиска - работу должен выполнять уникальный некластеризованный индекс.

Ответы [ 3 ]

9 голосов
/ 14 декабря 2010

Если ваш ключ - GUID, то некластеризованный индекс для него, вероятно, так же эффективен, как кластеризованный индекс для него.Это потому, что на GUID вы никогда не сможете сканировать диапазон (что может означать between 'b4e8e994-c315-49c5-bbc1-f0e1b000ad7c' and '3cd22676-dffe-4152-9aef-54a6a18d32ac' ??).При ширине 16 байтов ключ кластеризованного индекса GUID шире, чем идентификатор строки, который вы получили бы из кучи, поэтому индекс NC для guid PK на самом деле является стратегией, которую можно защитить в обсуждении.

Но если сделать первичный ключ ключом кластеризованного индекса, то не - единственный способ построить кластерный индекс в вашей куче.У вас есть другие частые запросы, которые запрашивают диапазоны по определенному столбцу?Типичными кандидатами являются столбцы типа date, state или deleted.Если вы это сделаете, то вам следует подумать о том, чтобы сделать эти столбцы ключом кластеризованного индекса (он не должен быть уникальным), поскольку это может помочь в запросах, которые запрашивают диапазоны, например «все записи вчера».

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

Переход к вашим точкам:

Почти наверняка нужно создать кластеризованный индекс для каждой таблицы в вашей базе данных.Если таблицы нет.Производительность большинства распространенных запросов выше.

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

Кластерные индексы не всегда плохи для GUID ... все зависит отпотребности вашего приложения.Скорость INSERT пострадает, но скорость SELECT будет улучшена.

Будет улучшен только выбор датчика SELECT: SELECT ... WHERE key='someguid';.Запросы по идентификатору объекта и поиску внешнего ключа получат выгоду от этого кластерного индекса.Индекс NC также может обслуживать ту же цель.

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

Неверно.Вставка в позицию в индексе не должна перемещать данные.Худшее, что может случиться, это разделение страниц.Разделение страницы (как-то) дорого, но это не конец света.Вы комментируете, что все данные (или, по крайней мере, «значимая» часть) должны быть перемещены, чтобы освободить место для новой строки, это далеко не так.

ClusteredИндекс GUID является нормальным в ситуациях, когда GUID имеет значение и повышает производительность, размещая связанные данные близко друг к другу http://randommadness.blogspot.com/2008/07/guids-and-clustered-indexes.html

Я не могу представить сценарий, в котором GUID может иметьданные'.GUID - это типичная случайная структура. Как два случайных идентификатора GUID могут быть связаны любым способом?Сценарий, который дает Дональд, имеет лучшее решение: Устранение конфликта PAGELATCH на высококонкурентных рабочих нагрузках INSERT , который дешевле в реализации (требуется меньше памяти) и работает также для уникальных ключей (решение в связанной статье не подойдетуникальные ключи, только для внешних ключей).

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

Для зондов (поиск конкретного уникального ключа) да.Индекс NC равен почти так же быстро, как кластеризованный индекс (для поиска индекса NC требуется и необходим дополнительный поиск ключа для выборки в остальных столбцах).Если кластеризованный индекс сияет, это сканирование диапазона, поскольку кластеризованный индекс может охватывать любой запрос, тогда как индекс NC, который может потенциально может удовлетворить тот же диапазон, может потерять покрытие 1068 * и срабатывает Индекс переломного момента .

2 голосов
/ 14 декабря 2010

Я бы также порекомендовал вам прочитать Кимберли Триппа "Дебаты о кластеризованном индексе продолжаются ... , в котором она довольно четко описывает все преимущества наличия * хорошего ключа кластеризации по сравнению с наличиемкуча.

Практически все операции выполняются быстрее - да! даже вставки и обновления!

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

Ваша лучшая ставка - это ключ, который является узким, стабильным, уникальным и постоянно растущим - столбец типа INT IDENTITY идеально соответствует всем этим требованиям.

Для получения дополнительной информации о причинахGUID не делает хороший ключ кластеризации, а о том, насколько он плох, читайте в других публикациях Кима Триппа в блоге:

1 голос
/ 21 ноября 2012

Я могу порекомендовать книгу «Объяснение производительности SQL» - это книга на 200 страниц об индексах.

В ней также упоминается, когда производительность кластерных индексов хуже, чем у обычных индексов.Одна из проблем заключается в том, что сам кластерный индекс является B-деревом.Поэтому, когда у вас есть другие индексы в той же таблице, они не могут указывать на указанную строку - вместо этого они указывают на «ключ» в кластеризованном индексе, поэтому «путь» к данным становится длиннее.

...