Каковы соображения производительности между использованием широкого PK против отдельного синтетического ключа и UQ?

10

У меня есть несколько таблиц, в которых записи могут быть однозначно идентифицированы в нескольких широких областях бизнеса. В прошлом я использовал эти поля в качестве PK, имея в виду следующие преимущества:

  • Простота; нет посторонних полей и только один индекс
  • Кластеризация обеспечивает быстрые объединения слиянием и фильтры на основе диапазона.

Тем не менее, я слышал случай, созданный для создания искусственного IDENTITY INTPK, и вместо этого применение бизнес-ключа с отдельным UNIQUEограничением. Преимущество состоит в том, что узкий PK делает для намного меньших вторичных индексов.

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

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

Джон на все руки
источник
1
Вы можете найти это или это полезным среди других вопросов на сайте
Джек говорит попробуйте topanswers.xyz

Ответы:

11

Нет существенного недостатка в использовании естественного ключа в качестве кластерного индекса

  • нет некластеризованных индексов
  • нет внешних ключей, ссылающихся на эту таблицу (это родительская строка)

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

Там, где у вас есть FK или NC-индексы, использование узкого числового увеличивающегося кластеризованного индекса имеет свои преимущества. Вы повторяете только несколько байтов данных для каждой записи NC или FK, а не бизнес / натуральный ключ.

Что касается того, почему, прочитайте тоже 5 статей из Google

Обратите внимание, я избегал использования «первичного ключа».

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

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

ГБН
источник
+1 для справки миссис Трипп отличные статьи в индексации.
Фабрицио Араужо
2
+1 за то, что производительность не имеет ничего общего с первичными ключами и все, что связано с индексами.
nvogel
4

Хотя я рискую констатировать очевидное, индекс суррогатного ключа (идентификационный номер) полезен, если вам нужно найти вещи по их идентификационному номеру. Пользователи не собираются иметь дело с идентификатором номера; они будут иметь дело с читаемым человеком текстом. Таким образом, вы должны много раз передавать текст и его идентификационный номер, чтобы пользовательский интерфейс мог отображать текст и работать с идентификационным номером.

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

Иногда вы можете улучшить производительность, используя идентификаторы в качестве внешних ключей, но это не абсолютное улучшение. В нашей системе OLTP внешние ключи, использующие естественные ключи, превосходили внешние ключи, используя идентификаторы в тестовом наборе из примерно 130 (я думаю) репрезентативных запросов. (Поскольку важная информация часто переносится в ключах, использование естественных ключей позволяет избежать большого количества объединений.) Среднее ускорение составило 85 раз (объединения, использующие номера идентификаторов, возвращали строки в 85 раз дольше).

Тесты показали, что объединения по номерам идентификаторов не будут выполняться быстрее, чем чтение по естественным ключам в нашей базе данных, пока определенные таблицы не достигнут многих миллионов строк. Ширина строки во многом связана с этим - более широкие строки означают, что на страницу помещается меньше строк, поэтому вам нужно прочитать больше страниц, чтобы получить 'n' строк. Почти все наши таблицы в 5NF; большинство таблиц довольно узкие.

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

Майк Шеррилл 'Cat Recall'
источник
3

У меня есть целая база данных oltp, разработанная с использованием столбцов идентификации для кластеризации + ПК. Он работает довольно быстро при вставке / поиске, но я видел несколько проблем:
1. опция заполнения индекса бесполезна, потому что вставки происходят только до конца индекса
2. больше места для хранения. У меня есть таблицы с десятками миллионов записей, и 1 int занимает место само по себе. Каждая таблица со столбцом идентификаторов для ее pk должна иметь другой индекс для бизнес-запросов, поэтому требуется еще больше места для хранения.
3. масштабируемость. Это худшая проблема. Поскольку каждая вставка идет до конца индекса, каждая вставка будет подчеркивать только конец индекса (распределение, ввод для записи и т. Д.). Используя бизнес-ключ в качестве ключа кластеризации, вы можете равномерно распределить вставки по индексу. Это означает, что вы просто устранили большую точку доступа. Вы можете легко использовать больше файлов для индексации, каждый файл на отдельном диске, каждый диск работает отдельно.

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

Я хотел бы предложить следующее (по крайней мере для oltp db):
1. использовать в качестве ключа кластеризации правильные столбцы в правильном порядке для оптимизации наиболее частых запросов
2. использовать pk правильные столбцы, которые имеют смысл для вашей таблицы

Если кластеризованный ключ не простой и содержит символы (char [], varchar, nvarchar), я думаю, что ответ «это зависит», вы должны проанализировать каждый случай индивидуально.

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

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

Каталин Адлер
источник
4
Ваша концепция «горячей точки» - это миф: dba.stackexchange.com/questions/1584/… А когда вы говорите: «Теперь вам стало лучше». Вы отметили?
ГБН
4
Да, записи выполняются в памяти, а не непосредственно на диск. Если вы записываете 20 новых строк на страницу, то при выполнении контрольной точки выполняется только 1 физическая запись в файл данных.
Мрденный
@mrdenny с достаточным количеством вставок, записывающих все в конец индекса, будет отправлять все запросы записи в один и тот же файл. Я подозреваю, что при использовании обычных транзакций oltp этот сценарий будет трудно воспроизвести, но использование некоторых специальных сценариев, таких как массовая / пакетная вставка записей, использование ssis для перемещения некоторых бизнес-данных приведет вас туда.
Каталин Адлер
1
@ user973156 да, все запросы будут выполняться для одного и того же файла, но записи фактически не отправляются на диск до контрольной точки, которая происходит только каждую минуту (по умолчанию) или когда буфер записи заполнен на 50%. Неважно, как вы пишете данные, это правило по-прежнему применяется.
Мрденный
2
@ user973156 Использование случайно распределенного ключа кластеризации приведет к фрагментации индекса. Фрагментация индекса вызовет проблемы с производительностью. И ваша таблица станет достаточно большой, чтобы выполнение дефрагментации индекса заняло «много времени», и заняло бы пространство журнала и, возможно, пространство tempDB. Когда такие люди, как Кимберли Трипп, говорят мне, что это хорошая идея, я слушаю. ( sqlskills.com/BLOGS/KIMBERLY/post/… )
Мэтт М
2

С точки зрения производительности выбор того, какой ключ является «первичным», совершенно не имеет значения. Нет никакой разницы между использованием PRIMARY KEY и УНИКАЛЬНОГО ограничения для обеспечения исполнения ваших ключей.

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

nvogel
источник