EDITB-cây, cơ sở dữ liệu, tuần tự so với chèn ngẫu nhiên và tốc độ. Ngẫu nhiên đang thắng
@Remus đã sửa mẫu thử nghiệm của tôi. Bạn có thể xem phiên bản sửa chữa trên câu trả lời của mình bên dưới.
tôi đã đề nghị thay thế INT với DECIMAL (29,0) và kết quả là:
Decimal: 2133
GUID: 1836
chèn ngẫu nhiên vẫn đang chiến thắng, ngay cả với một hàng lớn hơn một phần.
Mặc dù các giải thích cho biết chèn ngẫu nhiên chậm hơn các chuỗi tuần tự, các điểm chuẩn này cho thấy chúng rõ ràng nhanh hơn. Những lời giải thích tôi nhận được không đồng ý với các tiêu chuẩn. Do đó, câu hỏi của tôi vẫn tập trung vào cây xanh, chèn liên tục và tốc độ.
...
tôi biết từ kinh nghiệm rằng b-cây có hiệu suất khủng khiếp khi dữ liệu được thêm vào chúng liên tục (không phân biệt hướng). Tuy nhiên, khi dữ liệu được thêm ngẫu nhiên, hiệu suất tốt nhất thu được.
Điều này rất dễ dàng để chứng minh với mức độ thích của RB-Tree. Việc ghi tuần tự gây ra số lượng cân bằng cây tối đa được thực hiện.
Tôi biết rất ít cơ sở dữ liệu sử dụng cây nhị phân, nhưng thay vì sử dụng các cây cân bằng n-trật tự. Tôi logic giả sử họ bị một số phận tương tự như cây nhị phân khi nói đến đầu vào tuần tự.
Điều này làm tôi tò mò.
Nếu điều này là như vậy, thì người ta có thể suy ra rằng việc viết các ID tuần tự (chẳng hạn như trong IDENTITY (1,1)) sẽ khiến nhiều số dư của cây xảy ra. Tôi đã thấy nhiều bài viết tranh luận chống lại GUID là "những điều này sẽ gây ra ghi ngẫu nhiên". Tôi không bao giờ sử dụng GUID, nhưng nó đánh tôi rằng điểm "xấu" này trên thực tế là một điểm tốt.
Vì vậy, tôi quyết định thử nghiệm nó. Đây là mã của tôi:
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
Lưu ý rằng tôi không trừ bất cứ lúc nào cho việc tạo ra GUID cũng không cho kích thước thêm đáng kể của hàng. Các kết quả trên máy tính của tôi như sau:
Int: 17,340 ms GUID: 6746 ms
Điều này có nghĩa rằng trong thử nghiệm này, chèn ngẫu nhiên của 16 byte là gần 3 lần nhanh hơn hơn tuần tự chèn 4 byte.
Có ai muốn nhận xét về điều này không?
Ps. Tôi hiểu rằng đây không phải là một câu hỏi. Đó là lời mời thảo luận và điều đó có liên quan đến việc học lập trình tối ưu.
Thêm một char (3000) cột hoặc char (500) cột để giảm mật độ hàng mỗi trang. Điều gì sẽ xảy ra khi chạy lần 2? DB có phải phát triển không? Sau đó thêm một chỉ mục không được nhóm vào cột char (nếu <900). Tôi muốn một cái gì đó liên quan nhiều hơn đến cuộc sống thực ... – gbn
Tôi đã làm điều đó (char (3000)). Kết quả: Int: 7,406; GUID: 22,286. Char (300): Int: 6630, GUID: 5,816. Tại sao? – IamIC