【问题标题】:Sequential Guid and fragmentation顺序引导和碎片
【发布时间】:2011-03-27 21:02:55
【问题描述】:

我试图了解顺序 guid 的性能如何优于常规 guid。

是否因为使用常规 guid,索引使用 guid 的最后一个字节进行排序?由于它是随机的,它会导致很多碎片和页面拆分,因为它经常将数据移动到另一个页面以插入新数据?

顺序 guid 正因为它是顺序的,它会导致更少的页面拆分和碎片?

我的理解正确吗?

如果有人能对这个主题有更多的了解,我将不胜感激。

谢谢

编辑:

顺序 guid = NEWSEQUENTIALID(),

常规 guid = NEWID()

【问题讨论】:

  • 您可能想要定义“顺序 guid”,尤其是“常规 guid”的含义。
  • @Greg:我相信他的意思是 NEWSEQUENTIALID() 生成的“顺序 guid”与 NEWID() 生成的“常规 guid”

标签: sql-server guid database-fragmentation


【解决方案1】:

我听从 Kimberly L. Tripp 在这个话题上的智慧:

但是,一个非连续的 GUID - 像一个有它的价值观的人 在客户端生成(使用 .NET) 或由 newid() 函数生成 (在 SQL Server 中)可能非常糟糕 选择——主要是因为 它在 基表还因为它 尺寸。它不必要的宽(它是 4 比基于 int 的身份宽倍 - 这可以给你 20 亿(真的,40 亿)独特的行)。和, 如果你需要超过 20 亿 总是可以使用 bigint(8 字节 int) 并获得 263-1 行。

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

【讨论】:

  • 使用 Sequential Guid,因为它是连续的,从技术上讲,所有新的索引页面在理论上都是连续的,从而提高了性能。我理解正确吗?对于常规 guid,由于它是随机的,因此记录将遍布各处,因此执行带有范围的常规 select 语句可能会很慢?
  • @pdiddy - 既然“随机”GUID 不是连续的,为什么要选择其中的一个范围?
  • 您对顺序与随机性质的看法是正确的,但真正的痛苦在于 INSERT 而不是 SELECT。
  • 我明白了,插入是一个真正的痛苦,因为页面拆分和碎片。但是带有连接的选择也会很痛苦,因为它必须做很多寻找?我的意思是加入有 PK 也是常规 guid 的表
【解决方案2】:

你的问题已经说的差不多了。

使用顺序 GUID / 主键,新行将一起添加到表的末尾,这使得 SQL 服务器的事情变得容易。相比之下,随机主键意味着可以将新记录插入表中的任何位置——表的最后一页很有可能在缓存中(如果这是所有读取的地方),但是缓存中的表中间的随机页面相当低,这意味着需要额外的 IO。

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

【讨论】:

  • 谢谢!我只是想确认我理解正确。
【解决方案3】:

可以使用util named ostress 来可视化整个图片。 例如。您可以创建两个表:一个具有 normal 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)
);

然后使用给定的实用程序,您可以运行多个插入,并选择有关索引碎片的统计信息:

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       

正如您在插入顺序生成的 GUID 时看到的那样,索引的碎片要少得多,因为插入操作会导致新的页面分配更少。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    相关资源
    最近更新 更多