Создание первичного ключа guid для самого быстрого запроса, где выбрать guid (guid1, guid2, guid3 ...) - PullRequest
2 голосов
/ 01 июня 2009

Существует требование использовать GUID в качестве первичных ключей. Правильно ли я думаю, что

ProductID UNIQUEIDENTIFIER NOT NULL 
ROWGUIDCOL DEFAULT (NEWSEQUNTIALID()) PRIMARY KEY CLUSTERED 

даст самый быстрый выбор для предложения where

productid in ( guid1 , guid2 ,..., guidn )

и не ухудшается, не сгруппированы

natural_key like 'Something*'

независимый выбор. Таблица для запросов только пользователями и созданная / воссозданная программно с нуля.

Ответы [ 3 ]

3 голосов
/ 01 июня 2009

Тот факт, что вы используете GUID в качестве кластерного индекса, определенно отрицательно скажется на вашей производительности. Даже с NEWSEQUENTIALGUID GUID на самом деле не последовательны - они только частично. Их случайность по своей природе определенно приведет к более высокой фрагментации индекса и, следовательно, к менее оптимальному времени поиска.

Кроме того, если в качестве кластеризованного ключа у вас есть 16-байтовый GUID, он будет добавлен в любой некластеризованный индекс в этой таблице. Это может звучать не так уж плохо, но если у вас есть 10 миллионов. строк, 10 некластеризованных индексов, использование 16-байтового GUID против 4-байтового INT будет стоить вам 1,2 ГБ памяти, потраченной впустую - и не только на диск (что дешево), но и в память вашего сервера SQL (так как Сервер SQL всегда загружает целые 8 тыс. Страниц в 8 тыс. Блоков памяти, независимо от того, насколько они заполнены или пусты).

Я вижу смысл в использовании GUID в качестве первичного ключа - они почти на 100% гарантируют уникальность, привлекательны для разработчиков. НО: как кластерный ключ, это кошмар для вашей базы данных.

Моя лучшая практика: если мне действительно нужен GUID в качестве первичного ключа, я добавляю 4-байтовую INT IDENTITY в таблицу, которая затем служит кластеризованным ключом - результаты в этом случае намного лучше!

Если у вас есть некластеризованный первичный ключ, ваши запросы, использующие список идентификаторов GUID, будут такими же быстрыми, как если бы он был кластеризованным первичным ключом, и без использования GUID для кластеризованного ключа ваша таблица будет работать еще лучше в конец.

Узнайте больше о кластеризованном ключе и о том, почему так важно выбрать правильный в блоге Кимберли Триппса - Королеве индексации, и он может объяснить вещи гораздо лучше, чем я:

Марк

1 голос
/ 01 июня 2009

Кроме того, что GUID плохой (ответ от marc_s), у вас также есть предложение IN. Это клюет до:

productid = guid1 OR productid = guid2 OR ... OR productid = guidn

... на практике, что тоже не оптимально.

Как правило, natural_key like 'Something%', скорее всего, будет лучше для кластеризованного индекса в вашем ключевом столбце natrual.

0 голосов
/ 01 июня 2009

Кластерный индекс лучше всего подходит для диапазона поиска, поэтому он может удовлетворить ваш запрос:

productid in ( guid1 , guid2 ,..., guidn )

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

Кроме того, я думаю, что вы можете использовать NEWID () вместо NEWSEQUENTIALID ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...