Есть ли НАСТОЯЩАЯ разница в производительности между первичными ключами INT и VARCHAR? - PullRequest
151 голосов
/ 02 декабря 2008

Есть ли ощутимая разница в производительности между использованием INT и VARCHAR в качестве первичного ключа в MySQL? Я хотел бы использовать VARCHAR в качестве первичного ключа для списков ссылок (например, штаты США, коды стран), и коллега не будет указывать INT AUTO_INCREMENT в качестве первичного ключа для всех таблиц.

Мой аргумент, как детально здесь , заключается в том, что разница в производительности между INT и VARCHAR незначительна, поскольку для каждой ссылки на внешний ключ INT требуется JOIN, чтобы понять смысл ссылки, ключ VARCHAR непосредственно представить информацию.

Итак, есть ли у кого-нибудь опыт использования этого конкретного варианта использования и связанные с ним проблемы производительности?

Ответы [ 14 ]

1 голос
/ 28 мая 2014

Я столкнулся с той же дилеммой. Я сделал DW (схему Созвездия) с 3 таблицами фактов: Дорожно-транспортные происшествия, Транспортные средства при несчастных случаях и Несчастные случаи при авариях. Данные включают все несчастные случаи, зарегистрированные в Великобритании с 1979 по 2012 год, и 60 таблиц измерений. Всего около 20 миллионов записей.

Связи таблиц фактов:

+----------+          +---------+
| Accident |>--------<| Vehicle |
+-----v----+ 1      * +----v----+
     1|                    |1
      |    +----------+    |
      +---<| Casualty |>---+
         * +----------+ *

RDMS: MySQL 5.6

Собственно индекс несчастных случаев - это varchar (цифры и буквы) с 15 цифрами. Я старался не иметь суррогатных ключей, как только индексы аварий никогда не изменятся. На компьютере i7 (8 ядер) DW стал слишком медленным для запроса после 12 миллионов записей загрузки в зависимости от размеров. После долгих переделок и добавления суррогатных ключей bigint я получил увеличение скорости в среднем на 20%. Тем не менее, к низкой производительности, но действительная попытка. Я работаю в MySQL настройки и кластеризации.

0 голосов
/ 23 марта 2018

Позвольте мне сказать «да», безусловно, есть разница, учитывая объем производительности («из коробки»):

1 - Использование суррогата int быстрее в приложении, поскольку вам не нужно использовать ToUpper (), ToLower (), ToUpperInvarient () или ToLowerInvarient () в вашем коде или в вашем запросе, и эти 4 функции имеют разные критерии производительности , См. Правила производительности Microsoft по этому вопросу. (выполнение приложения)

2 - Использование суррогата int гарантирует, что ключ не изменится с течением времени. Даже коды стран могут измениться, см. Википедию, как коды ISO менялись с течением времени. Это займет много времени, чтобы изменить первичный ключ для поддеревьев. (производительность обслуживания данных)

3 - Кажется, есть проблемы с решениями ORM, такими как NHibernate, когда PK / FK не int. (производительность разработчика)

0 голосов
/ 27 апреля 2017

Как обычно, нет общих ответов. 'Это зависит!' и я не шучу Мое понимание исходного вопроса заключалось в том, что ключи в небольших таблицах - например, страна (целочисленный идентификатор или код char / varchar) - являются внешним ключом для потенциально огромной таблицы, такой как таблица адресов / контактов.

Здесь есть два сценария, когда вы хотите вернуть данные из БД. Во-первых, это запрос типа «список / поиск», в котором вы хотите перечислить все контакты с кодами или названиями штатов и стран (идентификаторы не помогут, и, следовательно, потребуется поиск). Другой сценарий получения по первичному ключу, который показывает одну запись контакта, в которой необходимо указать название штата и страны.

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

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

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

0 голосов
/ 02 декабря 2008

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

...