Почему INT не более эффективен, чем UNIQUEIDENTIFIER (согласно плану выполнения)?

У меня есть родительская таблица и дочерняя таблица, где столбцы, которые присоединяются к ним вместе, являются типом UNIQUEIDENTIFIER.

Дочерняя таблица имеет кластерный индекс на столбце, который соединяет ее с родительской таблицей (ее PK, который также кластеризируется).

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

Когда я запрашиваю для известного 20 записей из родительской таблицы, вытягивая во всех связанных записях из дочерних таблиц, я получаю идентичные затраты запроса через обоих, т.е. 50/50, стоивший за пакеты.

Если это верно, то мой гигантский проект изменить все таблицы как это, кажется, бессмыслен, кроме ускорения вставляет. Кто-либо может обеспечить какой-либо свет на ситуации?


Править:

Вопрос не, о котором более эффективно, но почему план выполнения запросов показывает оба запроса стоением того же?

6
задан cjk 19 March 2010 в 09:53
поделиться

3 ответа

Поиск по ключу в кластеризованном индексе практически одинаков для ключа размером 4 байта, 16 байт или 160 байт. Стоимость сравнения слотов с предикатом - это просто шум в общей стоимости запроса (подготовка к выполнению, подготовка контекста выполнения, открытие наборов рядов, поиск страниц и т.д.), даже если не задействован IO.

Хотя никто не будет спорить, что GUID и INT находятся в равных условиях, сравнение всего 20 запросов не выявит различий. Одно, что вы можете измерить немедленно, - это пространство: экономия 12 байт на строку и на страницу без листа в кластерном индексе, плюс 12 байт на каждую страницу листа в некластерных индексах - все это складывается на миллионах строк и десятках таблиц и индексов. Меньше места означает меньше IO, лучшую производительность кэша памяти, лучшее качество в целом, и это можно измерить, но вам нужно измерять реальные нагрузки, а не жалкие 20 строк поиска.

В лабораторных условиях вы сможете измерить разницу в скорости между поиском INT и GUID, но это не должно быть вашей целью. Аргумент INT vs. GUID не обусловлен чем-то вроде 5% прироста производительности при поиске, он обусловлен экономией места и случайностью Guid, приводящей к фрагментации. Оба этих показателя очень легко измерить, и они сами по себе являются убедительным аргументом в пользу INT, нет необходимости приводить аргумент о производительности поиска.

4
ответ дан 10 December 2019 в 02:46
поделиться

Намного эффективнее.

Int намного меньше. Это означает, что вы получаете гораздо меньшие индексы, что означает, что вы намного лучше используете память и время загрузки для доступа к индексу. Однако это во многом зависит от того, насколько велики ваши таблицы и что вы с ними делаете.

4
ответ дан 10 December 2019 в 02:46
поделиться

В дополнение к тому, что сказал Remus, использование GUID для кластеризованных индексов приведет к их огромной фрагментации в большинстве случаев, влияя на производительность запросов с точки зрения IO. Это происходит, когда вы не используете последовательно генерируемые guid, что, как я полагаю, в основном происходит, когда приложение генерирует guid вне базы данных. Для создания последовательного guid ("большего", чем ранее сгенерированный в базе данных) необходимо использовать функцию newsequentialid()

Сравнение стоимости двух планов в одной партии не является точным во всех случаях. Стоимость оценивается, в частности, по количеству операций ввода-вывода, необходимых для выполнения запроса. В небольших базах данных разница между INT и GUID не изменит IO достаточно сильно, чтобы показать разницу в планах выполнения.

1
ответ дан 10 December 2019 в 02:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: