Является ли «Избегать создания кластеризованного индекса на основе возрастающего ключа» мифом о SQL Server 2000 дней?

22

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

Разработка базы данных началась во времена SQL Server 6.0.

Одним из правил, которым следовали с самого начала, было: « Избегайте создания кластеризованного индекса на основе увеличивающегося ключа , как вы найдете в этих советах по оптимизации индекса» .

Теперь, используя SQL Server 2005 и SQL Server 2008, у меня сложилось впечатление, что обстоятельства изменились. Между тем, эти столбцы первичного ключа являются идеальными первыми кандидатами для кластеризованного индекса таблицы.

bernd_k
источник

Ответы:

34

Миф восходит к SQL Server 6.5, в котором добавлена ​​блокировка на уровне строк . И намекнул на это Кален Делани .

Это было связано с «горячими точками» использования страницы данных и тем фактом, что была заблокирована целая страница 2 КБ (страницы SQL Server 7 и более поздние версии 8 КБ), а не вставленная строка Правка, февраль 2012 г.

Найдена авторитетная статья Кимберли Л. Триппа

«Дискуссия по кластерному индексу продолжается ...»

Горячие точки - это то, что мы очень старались избегать до установки SQL Server 7.0 из-за блокировки на уровне страниц (и именно здесь термин «горячая точка» стал отрицательным). На самом деле, это не должно быть отрицательным термином. Однако, поскольку механизм хранения был повторно спроектирован / изменен (в SQL Server 7.0) и теперь включает в себя истинную блокировку на уровне строк, эта мотивация (чтобы избежать горячих точек) больше не существует.

Изменить, май 2013

Ссылка в ответе lucky7_2000, кажется, говорит о том, что горячие точки могут существовать, и они вызывают проблемы. Однако в статье используется неуникальный кластеризованный индекс TranTime. Это требует добавления уникального кода. Что означает, что индекс не является строго монотонно увеличивающимся (и слишком широким). Ссылка в этом ответе не противоречит этому ответу или моим ссылкам

На личном уровне я проснулся в базах данных, где я вставил десятки тысяч строк в секунду в таблицу, в которой столбец bigint IDENTITY является кластеризованным PK.

ГБН
источник
23

Подводя итог, в современных версиях SQL Server кластерный ключ в столбце идентификаторов является предпочтительным вариантом в наши дни.

mrdenny
источник
Коротко, просто, к сути, так что это получает мой +1. Не забудьте проверить ссылку на SQLSkills, так как там много полезной информации.
AndrewSQL
12
Это звучит как команда. Никаких объяснений или логики, чтобы почему мы должны ...
ГБН
Это не только звучит как команда, но и неправильно. Любая база данных, выполняющая очень большое количество операций вставки в секунду, столкнется с проблемами горячей точки, если вы используете последовательные ключи.
Томас Кейсер,
1
Я сказал, предпочел, не требуется. Для обычных приложений, которые составляют 98% баз данных в мире, кластерный ключ в столбце идентификаторов работает просто отлично.
Мрденни
10

Кимберли Трипп имеет фантастический пост в блоге только на эту тему. Я мог бы перефразировать, но поверьте мне, я бы не сделал этого справедливо. Прочитайте. http://www.sqlskills.com/BLOGS/KIMBERLY/post/Ever-increasing-clustering-key-the-Clustered-Index-Debateagain!.aspx

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

Мэтт М
источник
4

проверьте этот пост:

http://blogs.msdn.com/b/sqlserverfaq/archive/2010/05/27/monotonically-increasing-clustered-index-keys-can-cause-latch-contention.aspx

создание кластеризованного индекса на основе инкрементного ключа может создать «горячие точки», которые плохо влияют на производительность ...

lucky7_2000
источник
1
+1 за предоставление этой ссылки. Там есть несколько интересных советов. Но я думаю, что результат был бы гораздо более убедительным, если бы он сравнил данный сценарий со сценарием с созданием некластеризованного индекса cidx_trantime для tblTransactions (TranTime) или какой-либо другой альтернативой. Помните, что когда вы генерируете такое количество данных, должны быть эффективные способы извлечения данных, вы не можете просто выбросить все в кучу.
bernd_k
@bernd_k: это плохой пример ссылки. Дочерняя
таблица
1
Тогда попробуйте этот эксперимент: kejser.org/boosting-insert-speed-by-generating-scalable-keys
Томас Кейсер