потеря производительности строк в качестве первичных ключей? - PullRequest
13 голосов
/ 12 февраля 2010

Каким было бы снижение производительности при использовании строк в качестве первичных ключей вместо bigints и т. Д.? Сравнение строк намного дороже, чем целочисленное сравнение, но с другой стороны, я могу себе представить, что внутренне СУБД будет вычислять хеш-ключи, чтобы уменьшить штраф.

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

Ответы [ 4 ]

4 голосов
/ 12 февраля 2010

с другой стороны, я могу себе представить, что внутренне СУБД будет вычислять хеш ключи, чтобы уменьшить штраф.

БД должна поддерживать B-Tree (или аналогичную структуру) с ключом, чтобы они были упорядочены.

Если ключ хешируется и сохраняется в B-дереве, было бы неплохо быстро проверить уникальность ключа - ключ все еще можно найти эффективно. Но вы не сможете найти эффективный для диапазон данных (например, с LIKE), потому что B-дерево больше не упорядочено в соответствии со значением String.

Так что я думаю, что большинство БД действительно хранит строку в B-дереве, которое может (1) занять на пробел больше, чем числовые значения и (2) требует, чтобы B-дерево было -balanced , если ключи вставлены в произвольном порядке (нет понятия увеличения значения, как с числовым pk).

Наказание на практике может варьироваться от незначительного до огромного. Все зависит от использования, количества строк, среднего размера строкового ключа, запросов, которые присоединяются к таблице и т. Д.

3 голосов
/ 12 февраля 2010

В нашем продукте мы используем varchar (32) для первичных ключей (GUID), и мы не сталкивались с проблемами производительности этого. Наш продукт представляет собой веб-сайт с экстремальной перегрузкой и очень важен для стабильности. Мы используем SQL Server 2005.

Редактировать: в наших самых больших таблицах у нас более 3 000 000 записей с множеством вставок и выборок из них. Я думаю, что в целом, преимущество перехода на int key будет очень низким, но проблемы при переходе очень высоки.

1 голос
/ 12 февраля 2010

Следует обратить внимание на разделение страниц (я знаю, что это может произойти в SQL Server - вероятно, то же самое в MySQL).

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

1 голос
/ 12 февраля 2010

Это зависит от нескольких факторов: СУБД, количества индексов, включающих эти столбцы, но в целом это будет более эффективно при использовании целых чисел, следующих за bigints.

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

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

...