Избегайте создания кластеризованного индекса на основе ключа увеличения - PullRequest
11 голосов
/ 14 марта 2011

Я получил эту подсказку от mssqlcity.com .Однако я не могу понять его объяснение.

Избегайте создания кластеризованного индекса на основе инкрементного ключа

Например, если таблица имеет первичный ключ с суррогатным целым числом, объявленный как IDENTITY, и кластеризованныйДля этого столбца был создан индекс, затем каждый раз, когда данные вставляются в эту таблицу, строки добавляются в конец таблицы.Когда будет добавлено много строк, может возникнуть «горячая точка».«Горячая точка» возникает, когда многие запросы пытаются одновременно прочитать или записать данные в одной и той же области.«Горячая точка» приводит к узкому месту ввода / вывода.Заметка.По умолчанию SQL Server создает кластерный индекс для ограничения первичного ключа.Таким образом, в этом случае вы должны явно указать ключевое слово NONCLUSTERED, чтобы указать, что для ограничения первичного ключа создается некластеризованный индекс.

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

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

Я не совсем понимаю причину узкого места ввода / вывода, о котором они говорят.Они говорят, что слишком много операций с одной и той же страницей замедлит работу диска?Как это произошло?Может кто-нибудь объяснить мне?

Ответы [ 3 ]

7 голосов
/ 14 марта 2011

Горячая точка, на которую они ссылаются, не является проблемой в SQL Server 2005 и более поздних версиях.

Что ИСПОЛЬЗУЕТСЯ для того, чтобы все ваши данные были записаны в одну и ту же область кластерного индекса и одинаковуюсектор (ы) на диске, который вызвал одновременное создание большого количества грязных страниц (грязные страницы - это страницы данных, которые были изменены, но не зафиксированы на диске), и при запуске сброса или контрольной точки это может вызвать проблемы.

Более новые версии не испытывают такого поведения из-за изменений в архитектуре ввода-вывода (насколько я понимаю).

4 голосов
/ 14 марта 2011

Все современные транзакционные базы данных (современные средства, разработанные в последнее десятилетие) используют журналирование транзакций.

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

Если десять потоков вставят десять записей в таблицу со столбцом IDENTITY, механизм создаст десять записей журнала транзакций (записанных одна за другой одним процессом, называемым Log Writer), а затем, когда придет время CHECKPOINT, эти записи будут записаны на соответствующие страницы данных (также одним процессом, называемым Checkpoint).

Поскольку они являются непрерывными, наиболее вероятно, что они будут записаны в одну страницу данных в одной операции I/O, и разделение страниц не может произойти, поскольку после них нет данных.

Таким образом, кластеризованный индекс для постоянно увеличивающегося ключа на более эффективнее, чем для случайного ключа.

4 голосов
/ 14 марта 2011

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

См. Также https://dba.stackexchange.com/questions/1584/is-avoid-creating-a-clustered-index-based-on-an-incrementing-key-a-myth-from-sq

Цитата также противоречит рекомендации (с той же страницы):

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...