РЕДАКТИРОВАТЬ
@ Ремус исправил мой тестовый шаблон.Вы можете увидеть исправленную версию в его ответе ниже.
Я принял предложение заменить INT на DECIMAL (29,0), и результаты были такими:
Десятичное число: 2133
GUID: 1836
Случайные вставки по-прежнему выигрывают, даже с немного большей строкой.
Несмотря на объяснения, которые указывают, что случайные вставки медленнее, чем последовательные, эти тесты показывают, что онивидимо быстрее.Объяснения, которые я получаю, не согласуются с критериями.Поэтому мой вопрос остается сфокусированным на b-деревьях, последовательных вставках и скорости.
...
Из опыта я знаю, что b-деревья имеют ужасную производительность, когда данные добавляются к ним последовательно(независимо от направления).Однако, когда данные добавляются случайным образом, достигается наилучшая производительность.
Это легко продемонстрировать с помощью подобного RB-дерева.Последовательные записи приводят к выполнению максимального количества балансов дерева.
Я знаю, что очень немногие базы данных используют двоичные деревья, но используют сбалансированные деревья n-порядка.Я логично предполагаю, что они испытывают схожую судьбу с бинарными деревьями, когда дело доходит до последовательных входов.
Это вызвало мое любопытство.
Если это так, то можно сделать вывод, что запись последовательных идентификаторов (например,как в 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 байтов было почти в 3 раза быстрее , чем последовательных вставок по 4 байта .
Кто-нибудь хотел бы прокомментировать это?
Ps.Я понимаю, что это не вопрос.Это приглашение к дискуссии, и оно имеет отношение к изучению оптимального программирования.