EDITB-деревья, базы данных, последовательные и случайные вставки и скорость. Случайный выигрыш
@Remus исправил мою тестовую модель. Вы можете увидеть исправленную версию своего ответа ниже.
Я принял предложение заменить INT с DECIMAL (29,0), и результаты были:
Decimal: 2133
GUID: 1836
Случайные вставки по-прежнему побеждает, даже с дробно большей строкой.
Несмотря на объяснения, указывающие, что случайные вставки медленнее, чем последовательные, эти тесты показывают, что они, по-видимому, быстрее. Объяснения, которые я получаю, не согласуются с эталонами. Поэтому мой вопрос остается сосредоточенным на b-деревьях, последовательных вставках и скорости.
...
Я знаю по опыту, что б дерева имеют ужасную производительность, когда данные добавляются к ним последовательно (независимо от направления). Однако, когда данные добавляются случайным образом, достигается наилучшая производительность.
Это легко продемонстрировать с подобными RB-Tree. Последовательная запись вызывает максимальное количество балансов деревьев.
Я знаю, что очень немногие базы данных используют двоичные деревья, а скорее используют сбалансированные деревья 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. Я понимаю, что это не вопрос. Это приглашение к обсуждению, и это актуально для обучения оптимальному программированию.
добавить символ столбца или обугленного столбец (3000) (500) для уменьшения плотности строк на странице. Что происходит во время второго запуска? Должен ли БД расти? Затем добавьте некластеризованный индекс в столбце char (если <900). Я бы предпочел что-то большее, связанное с реальной жизнью ... – gbn
Я сделал это (char (3000)). Результаты: Int: 7406; GUID: 22,286. Char (300): Int: 6630, GUID: 5816. Зачем? – IamIC