Недавно у нас был традиционный и постоянный (согласно поиску 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), представляет собой другой случай.
Заранее извиняюсь, я не большой гуру баз данных, поэтому мне сложно объяснить эти результаты.
Ваше здоровье,
Айдос