【发布时间】:2011-06-03 15:24:47
【问题描述】:
编辑
@Remus 更正了我的测试模式。您可以在下面的答案中看到更正后的版本。
我接受了将 INT 替换为 DECIMAL(29,0) 的建议,结果是:
十进制:2133
GUID:1836
随机插入仍然胜出,即使行稍大。
尽管解释表明随机插入比顺序插入慢,但这些基准测试表明它们显然更快。我得到的解释与基准不一致。因此,我的问题仍然集中在 b 树、顺序插入和速度上。
...
我从经验中知道,当数据按顺序(无论方向如何)添加到它们时,b 树的性能很差。但是,当数据随机添加时,会获得最佳性能。
这很容易用 RB-Tree 之类的东西来演示。顺序写入会导致执行最大数量的树平衡。
我知道很少有数据库使用二叉树,而是使用 n 阶平衡树。从逻辑上讲,我假设它们在顺序输入方面会遭受与二叉树相似的命运。
这激发了我的好奇心。
如果是这样,那么可以推断出写入顺序 ID(例如在 IDENTITY(1,1) 中)会导致树发生多次重新平衡。我看到 许多 帖子反对 GUID,因为“这些会导致随机写入”。我从不使用 GUID,但让我印象深刻的是,这个“坏”点实际上是一个好点。
所以我决定测试一下。这是我的代码:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[T1](
[ID] [int] NOT NULL
CONSTRAINT [T1_1] PRIMARY KEY CLUSTERED ([ID] ASC)
)
GO
CREATE TABLE [dbo].[T2](
[ID] [uniqueidentifier] NOT NULL
CONSTRAINT [T2_1] PRIMARY KEY CLUSTERED ([ID] ASC)
)
GO
declare @i int, @t1 datetime, @t2 datetime, @t3 datetime, @c char(300)
set @t1 = GETDATE()
set @i = 1
while @i < 2000 begin
insert into T2 values (NEWID(), @c)
set @i = @i + 1
end
set @t2 = GETDATE()
WAITFOR delay '0:0:10'
set @t3 = GETDATE()
set @i = 1
while @i < 2000 begin
insert into T1 values (@i, @c)
set @i = @i + 1
end
select DATEDIFF(ms, @t1, @t2) AS [Int], DATEDIFF(ms, @t3, getdate()) AS [GUID]
drop table T1
drop table T2
请注意,我不会因为行的相当大的额外大小而减少创建 GUID 的任何时间也不。我的机器上的结果如下:
内部:17,340 毫秒 GUID:6,746 毫秒
这意味着在此测试中,16 字节的随机插入比4 字节的顺序插入快几乎 3 倍。 p>
有人愿意对此发表评论吗?
附言。我知道这不是一个问题。这是一个讨论邀请,与学习最佳编程有关。
【问题讨论】:
-
添加 char(3000) 列或 char(500) 列以减少每页的行数密度。第二次运行时会发生什么? DB必须增长吗?然后在 char 列上添加一个非聚集索引(如果
-
我做到了 (char(3000))。结果:国际:7,406; GUID:22,286。字符(300):内部:6630,GUID:5,816。为什么?
标签: sql sql-server benchmarking clustered-index