編集
@Remus がテスト パターンを修正しました。以下の彼の回答で修正版を見ることができます。
INT を DECIMAL(29,0) に置き換えることを提案したところ、結果は次のようになりました。
10 進数: 2133
GUID: 1836
わずかに大きな行であっても、ランダム挿入はまだ勝っています。
ランダムな挿入はシーケンシャルな挿入よりも遅いことを示す説明にもかかわらず、これらのベンチマークはそれらが明らかに速いことを示しています。私が得ている説明は、ベンチマークと一致していません。したがって、私の質問は引き続き b ツリー、順次挿入、および速度に焦点を当てています。
...
経験から、B ツリーにデータが (方向に関係なく) 順次追加されると、パフォーマンスが大幅に低下することがわかっています。ただし、データをランダムに追加すると、最高のパフォーマンスが得られます。
これは、RB ツリーなどを使用して簡単に実証できます。順次書き込みにより、最大数のツリー バランスが実行されます。
二分木を使用するデータベースはほとんどなく、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 の作成や、行のかなりの余分なサイズのために時間を差し引いていないことに注意してください。私のマシンでの結果は次のとおりです。
Int: 17,340 ミリ秒 GUID: 6,746 ミリ秒
これは、このテストでは、16 バイトのランダム挿入が 4 バイトの順次挿入よりもほぼ3 倍高速であることを意味します。
これについてコメントしたい人はいますか?
Ps。これは質問ではないことがわかりました。これは議論への招待であり、最適なプログラミングの学習に関連しています。