У нас недавно был традиционный и постоянный (согласно поискам SO) аргумент о назначенных первичных ключах GUID против автоинкремента. Мы используем MSSQL 2008R2, NHibernate 2.05 и .NET 4.0.
Я довольно много гуглил и читал другие посты в SO о разнице в производительности вставки между использованием двух разных типов ключей. Большинство постов в блоге, похоже, были посвящены довольно старым версиям сервера MSSQL, поэтому я подумал, что попробую сравнить некоторые вставки и посмотреть, соответствуют ли они тому, что говорят люди.
Я написал простое приложение, которое просто вставляет 2 миллиона объектов по одной строке на сеанс в базу данных, и единственное различие между двумя запусками приложения - это тип ключа. Оба ключа сгруппированы - так что из моего прочтения это хороший случай для автоинкрементов и худший вариант для Guid.
При взгляде на результаты я был немного шокирован ...
Не желая, чтобы царство террора Зед Шоу обрушилось на меня за то, что я не выполнил надлежащий статистический анализ, я загрузил данные в R и сгенерировал график (см. Ниже) и получил следующее Сводная статистика:
Ключи GUID:
Мин .: 0,00
1-й квартиль: 0,00
Медиана: 0,00
Среднее: 1,975
Стандартное отклонение: 13,577490
3-й квартиль: 1,0
Макс .: 3824,0
Собственные (с автоматическим приращением) ключи
Мин: 0,00
1-й квартиль: 0,00
Медиана: 0,00
Среднее: 1.644
Стандартное отклонение: 12,491320
3-й квартиль: 0,00
Макс .: 1932,00
Предполагая, что должна быть линейная зависимость между размером таблицы и временем, которое требуется для вставки строки, я попытался вычислить регрессию наименьших квадратов, используя размер таблицы в качестве предиктора, и получил следующие результаты:
GUID : 0,002594
Родной : 0,002594
Наиболее важными для меня являются значения в квадрате r, поскольку в моем (по общему признанию) ограниченном понимании статистики нет никакой корреляции между размером таблицы и скоростью вставки в любом случае.
Меня беспокоит то, что результаты, которые я получаю, не соответствуют общепринятой мудрости, и мне интересно, может ли кто-нибудь в SO-земле помочь мне объяснить результаты. Я вижу несколько возможностей:
- Проблема производительности с GUID была проблемой с предыдущими версиями сервера MSSQL, однако больше не является проблемой.
- Я написал плохой эксперимент, и результаты, которые я получаю, бесполезны.
- Разница в 0,331 мс на самом деле значительна, если смотреть на производительность базы данных, и я не рассматриваю это значение разумно.
- Обращение к базе данных для получения идентификатора при использовании ключа идентификатора с автоинкрементом оказывает влияние на производительность.
- Использование четырехъядерного компьютера для локального тестирования означает, что достаточно свободного ЦП для индексации в фоновом потоке.
- Все статистические данные, которые я видел, относятся к необработанному SQL, использующему сгенерированные GUID, и что сценарий, который я тестирую (используя NHibernate), - это совсем другой случай.
Заранее прошу прощения, я не очень гуру баз данных, поэтому я изо всех сил пытаюсь объяснить эти результаты.
Приветствия
Айдос