Целочисленные, символьные и GUID-ключи в MS SQL

Сравнение производительности некоторых SQL-операций при использовании целочисленных, символьных и GUID-ключей. Тесты проводились на Microsoft Server 2000 и 2005.

Содержание теста

Тест создает в базе данных 6 таблиц. Таблицы Т1 и Т11 имеют целочисленные первичные ключи типа int, Т1 связана с Т11 в отношении "один-ко-многим". Имеются аналогичные таблицы Т2 и Т21 с символьными ключами типа char(15). В каждой таблице имеется индекс на первичный ключ. Таблицы Т11 и Т21 имеют также индексы на внешние ключи. Для GUID-ключей были добавлены таблицы T3 и T31. Этот тест проводился только на MS SQL 2005.

В тесте определятся параметры-переменные:

@ParentCount определяет количество записей в главной таблице
@ChildCount определяет количество записей в связанной таблице на каждую запись в главной
@StagesCount количество циклов повторения этапа выполнения запросов для получения усредненных результатов
@MaxNum максимальное значение для диапазона значений поля Num (0, @MaxNum]

В первой части теста выполняется создание и заполнение таблиц данными. Ключи генерируются последовательным образом, однако для символьных полей порядковый номер добавляемой записи преобразуется в "NKEY00000...", где N - порядковый номер, KEY0000 - символьное выражение, дополняющее длину преобразованного в строку номера до 15 (Это выполняет процедура GetCharKey).

Для полей Num в таблицах T1 и Т2 генерируются случайные значения в диапазоне (0, @MaxNum]. Значение @MaxNum следует выбирать меньшим в разы, чем количество записей в главной таблице.

Поля Title всех таблиц заполняются фиксированными значениями вида: "'Title T: KEY'", где Т - название таблицы, KEY - значение ее ключа, преобразованного в строку. Имеется возможность заполнять строки случайным образом, однако это резко увеличивает время, требуемое для заливки первоначальных данных. Тем не менее, для включения этого режима достаточно удалить комментарии в тексте вызов процедуры GetRandomString и установить комментарии на строку присвоения переменной @Title фиксированного значения.

Во второй части теста производятся запросы к обеим таблицам, вида:

SELECT @j = count(*)
   FROM T1 JOIN T11 ON T1.T1ID = T11.T1ID
   WHERE T1.Num = @k

Значение @k выбирается случайным образом из диапазона (0, @MaxNum]. Запрос представляет собой подсчет количества записей, попавших в запрос после эквисоединения двух таблиц по ключу с условием фильтрации по случайно выбираемым значением поля Num. При первоначально выбранных значениях @MaxNum меньших, чем @ParentsCount обеспечивается выборка более чем одной записи из главной таблицы и их соединение с записями из связанной таблицы. Поле, по которому происходит фильтрация также имеет индекс, избирательность которого напрямую зависит от соотношения @ParentsCount к @MaxNum. К каждой групп таблиц производится @ParentsCount запросов.

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

Исходный текст теста

Текст SQL-скрипта теста вы можете скачать по ссылке на файл mssql_keys_test.sql в конце страницы

Условия проведения теста

В разное время для проведения теста использовались две конфигурации.

Конфигурация 1: MS SQL Server 2000 Evaluation, установленный на ПК Pentium-II-300, RAM 256, HDD 20 Gb UltraATA-33. Операционная система: Windows NT Workstation 4 SP5.

Конфигурация 2: MS SQL Server 2005 Developer, установленный на ПК AMD Athlon 2400, RAM 1 Gb, HDD WesternDigital 240 Gb Serial ATA 300. Операционная система: Windows XP Pro SP2.

Под SQL Server в обоих случаях выделялось не более 192 Мб физической памяти. Размер тестовой БД - 500 Мб (исключает динамическое увеличение), журнала - 50 Мб, Размер временной БД (tempdb) - 300 Мб.

Параметры:

Параметр Значение на прогоне
Прогон 1 Прогон 2 Прогон 3
@ParentsCount 10 000 10 000 10 000
@ChildsCount 30 40 50
@StagesCount 10 10 10
@MaxNum 1 000 1 000 1 000

Таким образом, на каждом прогоне в группу таблиц заносится: 10 000 записей в главную и 300 000 (400 000 и 500 000) - в связанную. Выполняется 10 циклов выполнения запросов, по 10 000 к каждой группе таблиц в цикле (всего 100 000 запросов к каждой группе). Так как соотношение @ParentsCount к @MaxNum составляет на всех прогонах 10, то в среднем за каждый запрос с эквисоединением выбирается 10*@ChildsCount записей (300, 400 и 500, соответственно).

Результаты

Наиболее интересны несколько выявленных наблюдений:

  • Поиск по ключу символьного поля производится примерно так же быстро или даже быстрее, чем по целочисленному
  • MS SQL 2005 производит соединение по целочисленным ключам примерно в 2 раза быстрее своего предшественника (относительно скорости соединения по символьным ключам)
  • При использование GUID-ключей быстродействие сравнимо или даже лучше такового при целочисленных ключах
  • Мощность компьютера возросла: в 8 раз по частоте процессора, в 10 раз по частоте шины контролера диска (ОЗУ в 4 раза можно не учитывать, т.к. объемы данных не изменились). При этом скорость обработки запросов выросла только в 5-6 раз.
Тест и этап Результаты
Таблицы с целочисленными ключами, мсек Таблицы с символьными ключами, мсек Таблицы с GUID-ключами, мсек Соотношение времени (2):(3):(4), %
(1) (2) (3) (4) (5)
Прогон 1 Прогон 2 Прогон 3 (1) Прогон 1 Прогон 2 Прогон 3 Прогон 1

 

Прогон 2 Прогон 3 Прогон 1 Прогон 2 Прогон 3
MS SQL 2000 (конфигурация 1)                        
Заполнение данными 321003 396870 504393 355280 459153 665026 н/д н/д н/д 90 : 100 86 : 100 76 : 100
Выборка эквисоединением 7123 9555 10352 10042 13147 14743 н/д н/д н/д 70 : 100 73 : 100 70 : 100
Поиск по ключу 1475 1921 1899 1298 1546 1414 н/д н/д н/д 100 : 88 100 : 80 100 : 75
       
MS SQL 2005 (конфигурация 2)                        
Заполнение данными 64080 86670 100860 70233 102923 125313 61623 96703 107343 91 : 100 : 88 84 : 100 : 94 80 : 100 : 86
Выборка эквисоединением 821 996 1445 2312 2860 4388 1053 1135 1274 36 : 100 : 46 35 : 100 : 40 33 : 100 : 29
Поиск по ключу 244 265 263 241 198 213 214 180 202 100 : 99 : 88 100 : 75 : 68 100 : 81 : 77

С некластерными индексами
(конфигурация 2)

                       
Заполнение данными 67313 90470 108280 75906 113436 124986 72483 98063 133280 89 : 100 : 95 80 : 100 : 86 81 : 94 : 100
Выборка эквисоединением 1397 1882 3554 2199 2744 6086 970 1169 1855 64 : 100 : 44 69 : 100 : 43 58 : 100 : 30
Поиск по ключу 244 293 274 197 237 239 191 199 152 100 : 81 : 78 100 : 81 : 68 100 : 87 : 55

Примечание:

1 - для конфигурации с некластерными индексами доступная физическая память для SQL Server была увеличена до 256 Мб

Сергей Тарасов, июнь 2001. С дополнениями, февраль-апрель 2007

Оценка: 1 (Голосов 1)
Прикрепленный файлРазмер
mssql_keys_test.sql2.35 кб

Ответить

Содержание этого поля является приватным и не предназначено к показу.
  • Allowed HTML tags: <a> <em> <strong> <b> <i> <strike> <center> <del> <cite> <code> <pre> <ul> <ol> <li> <dl> <dt> <dd> <p> <br> <h1> <h2> <h3> <h4> <img> <hr> <sup> <sub> <blockquote>
  • Use <!--pagebreak--> to create page breaks.
  • You can enable syntax highlighting of source code with the following tags: <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".
  • Строки и параграфы переносятся автоматически.

Подробнее о форматировании

Captcha
Вопрос для предотвращения спама
Copy the characters (respecting upper/lower case) from the image.