我尝试了解如何顺序guid进行更好的比常规guid。

这是因为与正规guid,该指数使用的最后一个字节的guid排序?由于这是随机就会造成很多碎片和网页分裂,因为它经常将数据移到另一个网页以插入新数据?

顺序guid正弦它的顺序就会造成很多小页面分割和分裂?

我的理解正确吗?

如果任何人都可以棚更多的灯关于这个问题,我将认识到很多。

谢谢你

编辑:

顺序guid=NEWSEQUENTIALID(),

经常guid=NEWID()

有帮助吗?

解决方案

您已经差不多说,这一切在你的问题。

通过连续GUID /主键的新行会在表中,这使得事情很好的容易SQL服务器端被加在一起。在比较随机的主键意味着新的记录,可以在表中的任何地方插入 - 表在缓存中是最后一页的机会是相当可能的(如果这就是所有的读取会),但是机会在表中在高速缓存中被中间的随机页面是相当低的,这意味着附加的IO是必需的。

在最重要的是,将行插入到表的中间时,有是有没有足够的空间来插入额外的行的机会。如果是这种情况,那么SQL Server需要,以创造空间备案执行额外的昂贵的IO操作 - 避免这种情况的唯一方法是让分散的数据之间的差距,以允许额外的记录被插入(被称为填充因子),这本身会导致性能问题,因为数据是分布在多个页面,因此多个IO需要访问整个表。

其他提示

我推迟到金伯利L.特里普的智慧关于这一主题:

但是,GUID不顺序 像一个都有它的价值 中产生的客户(使用。NET) 或产生的newid()function (SQL服务器)可能是一个可怕的糟糕 选择-主要是因为 碎片,它创建的 基本表,但也因为它的 大小。这是不必要的广(这是4 次更广泛的比int基于身份 -可以给你2亿美元(真的,4亿美元)的唯一行)。而且, 如果你需要更多的超过2亿你 总是可以去一个bigint(8字节 int)和获得263-1行。

详细阅读: http://www.sqlskills.com/BLOGS/KIMBERLY/post/GUIDs-as-PRIMARY-KEYs-andor-the-clustering-key.aspx#ixzz0wDK6cece

要可视化的全貌 util的命名的 OSTRESS 可以使用。 例如。可以创建两个表:一个与正常 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的运行刀片的numbero约索引碎片统计的选择:

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:\进入\ 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       

可以与顺序地生成GUID看到被插入,索引小得多分段为插入操作导致新页分配罕见。

scroll top