Вопрос

Я пытаюсь понять, как последовательный GUID выполняет лучше, чем регулярный GUID.

Это связано с помощью регулярного GUID, индекс использует последний байт GUID для сортировки? Поскольку это случайно, это приведет к тому, что много фрагментации и расщепления страниц, поскольку он часто будет перемещать данные на другую страницу, чтобы вставить новые данные?

Последовательный GUID SINE SINE SEQUINT, он приведет к тому, что намного меньше расщепляется и фрагментация страниц?

Является ли мое понимание правильно?

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

Спасибо

РЕДАКТИРОВАТЬ:

Последовательный GUID = NewsexentialID (),

Регулярный GUID = NewID ()

Это было полезно?

Решение

Вы в значительной степени сказали все это в вашем вопросе.

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

Кроме того, при вставке рядов в середину таблицы имеется вероятность того, что не хватает места для вставки дополнительной строки. Если это так, то SQL Server должен выполнить дополнительные дорогие операции IO, чтобы создать место для записи - единственным способом, которым можно избежать этого, - это разброс, разбросанные среди данных, чтобы обеспечить вставленные дополнительные записи (известные как Фактор заполнения), который сам по себе вызывает проблемы с производительностью, потому что данные распространяются по большему количеству страниц, и поэтому больше IO требуется для доступа к всей таблице.

Другие советы

Я отложил мудрость Кимберли Л. Трипп на эту тему:

Но GUID, который не является последовательным - подобным таким, таким образом, имеющим его значения, сгенерированные в клиенте (используя .NET) или сгенерированные функцией NewID () (на SQL Server) могут быть ужасно плохой выбор - в первую очередь из-за фрагментации, который Это создает в базовом столе, но и из-за его размера. Это излишне широко (в 4 раза больше, чем интенсивная идентичность, которая может дать вам 2 миллиарда (действительно, 4 миллиарда) уникальных строк). И, если вам нужно более 2 миллиардов, вы всегда можете пойти с Bigint (8-байт INT) и получите 263-1 строк.

Подробнее: http://www.sqlskills.com/blogs/kimberly/post/guids-as-primary-keys-andor-the-clustering-key.aspx#ixz0WDK6CECE.

Визуализировать всю картину Умитана названа остерс может быть использован. Например, вы можете создать две таблицы: один с обычный GUID как PK, другой с последовательным GUID:

-- normal one
CREATE TABLE dbo.YourTable(
   [id] [uniqueidentifier] NOT NULL,
   CONSTRAINT [PK_YourTable] PRIMARY KEY NONCLUSTERED (id)
);
-- sequential one
CREATE TABLE dbo.YourTableSeq(
   [id] [uniqueidentifier] NOT NULL CONSTRAINT [df_yourtable_id]  DEFAULT (newsequentialid()),
   CONSTRAINT [PK_YourTableSeq] PRIMARY KEY NONCLUSTERED (id)
);

Затем с данным Util вы запускаете Nall of Instrics с выбором статистики о фрагментации индекса:

ostress -Slocalhost -E -dYourDB -Q"INSERT INTO dbo.YourTable VALUES (NEWID()); SELECT count(*) AS Cnt FROM dbo.YourTable; SELECT AVG_FRAGMENTATION_IN_PERCENT AS AvgPageFragmentation, PAGE_COUNT AS PageCounts FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, N'LIMITED') DPS INNER JOIN sysindexes SI ON DPS.OBJECT_ID = SI.ID AND DPS.INDEX_ID = SI.INDID WHERE SI.NAME = 'PK_YourTable';" -oE:\incoming\TMP\ -n1 -r10000

ostress -Slocalhost -E -dYourDB -Q"INSERT INTO dbo.YourTableSeq DEFAULT VALUES; SELECT count(*) AS Cnt FROM dbo.YourTableSeq; SELECT AVG_FRAGMENTATION_IN_PERCENT AS AvgPageFragmentation, PAGE_COUNT AS PageCounts FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, N'LIMITED') DPS INNER JOIN sysindexes SI ON DPS.OBJECT_ID = SI.ID AND DPS.INDEX_ID = SI.INDID WHERE SI.NAME = 'PK_YourTableSeq';" -oE:\incoming\TMP\ -n1 -r10000

Затем в файле E: Incoming TMP Query.out Вы найдете свою статистику. Мои результаты:

"Normal" GUID:
Records    AvgPageFragmentation     PageCounts           
---------------------------------------------- 
1000       87.5                     8                    
2000       93.75                    16                   
3000       96.15384615384616        26                   
4000       96.875                   32                   
5000       96.969696969696969       33                   
10000      98.571428571428584       70                   


Sequential GUID:
Records    AvgPageFragmentation     PageCounts           
---------------------------------------------- 
1000       83.333333333333343       6                    
2000       63.636363636363633       11                   
3000       41.17647058823529        17                   
4000       31.818181818181817       22                   
5000       25.0                     28                   
10000      12.727272727272727       55       

Как вы можете видеть с помощью последовательно сгенерированного руководства, индекс намного менее фрагментирован, поскольку операция вставки приводит к распределению новой страницы Rarer.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top