Tôi đã thử nghiệm 2 phương pháp ngẫu nhiên hóa dựa trên bộ dựa trên RAND () bằng cách tạo 100.000.000 hàng với mỗi phương pháp. Để cân bằng trường, đầu ra là một dấu nổi giữa 0-1 để bắt chước RAND (). Hầu hết mã là cơ sở hạ tầng thử nghiệm, vì vậy tôi tóm tắt các thuật toán ở đây:
(CAST(CRYPT_GEN_RANDOM(8) AS BIGINT)%500000000000000000+500000000000000000.0)/1000000000000000000 AS Val
RAND(Checksum(NewId()))
RAND()
Sử dụng CRYPT_GEN_RANDOM rõ ràng là ngẫu nhiên nhất vì chỉ có 0,000000001% cơ hội nhìn thấy thậm chí 1 bản sao khi lấy 10 ^ 8 số TỪ tập hợp 10 ^ 18 số. IOW chúng tôi không nên thấy bất kỳ bản sao và điều này không có! Tập hợp này mất 44 giây để tạo trên máy tính xách tay của tôi.
Cnt Pct
1 100.000000
Thời gian thực thi SQL Server: thời gian CPU = 134795 ms, thời gian đã trôi qua = 39274 ms.
IF OBJECT_ID('tempdb..
GO
WITH L0 AS (SELECT c FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS D(c))
,L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B)
,L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B)
,L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B)
SELECT TOP 100000000 (CAST(CRYPT_GEN_RANDOM(8) AS BIGINT)%500000000000000000+500000000000000000.0)/1000000000000000000 AS Val
INTO
FROM L3;
WITH x AS (
SELECT Val,COUNT(*) Cnt
FROM
GROUP BY Val
)
SELECT x.Cnt,COUNT(*)/(SELECT COUNT(*)/100 FROM
FROM X
GROUP BY x.Cnt;
Với gần 15 lệnh có độ lớn ít ngẫu nhiên hơn, phương pháp này không nhanh gấp đôi, chỉ mất 23 giây để tạo ra 100 triệu số.
Cnt Pct
1 95.450254
2 02.222167
3 00.034582
4 00.000409
5 00.000006
Thời gian thực thi SQL Server: thời gian CPU = 77156 ms, thời gian đã trôi qua = 24613 ms.
IF OBJECT_ID('tempdb..
GO
WITH L0 AS (SELECT c FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS D(c))
,L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B)
,L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B)
,L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B)
SELECT TOP 100000000 RAND(Checksum(NewId())) AS Val
INTO
FROM L3;
WITH x AS (
SELECT Val,COUNT(*) Cnt
FROM
GROUP BY Val
)
SELECT x.Cnt,COUNT(*)*1.0/(SELECT COUNT(*)/100 FROM
FROM X
GROUP BY x.Cnt;
Riêng RAND () là vô dụng đối với việc tạo dựa trên bộ vì vậy việc tạo đường cơ sở để so sánh độ ngẫu nhiên mất hơn 6 giờ và phải được khởi động lại nhiều lần để cuối cùng có được số hàng đầu ra phù hợp. Cũng có vẻ như sự ngẫu nhiên để lại rất nhiều điều mong muốn mặc dù tốt hơn là sử dụng tổng kiểm tra (newid ()) để gửi lại từng hàng.
Cnt Pct
1 99.768020
2 00.115840
3 00.000100
Do quá trình khởi động lại, không thể nắm bắt được thời gian thực hiện.
IF OBJECT_ID('tempdb..
GO
CREATE TABLE
GO
SET NOCOUNT ON;
GO
INSERT INTO
GO 100000000
WITH x AS (
SELECT Val,COUNT(*) Cnt
FROM
GROUP BY Val
)
SELECT x.Cnt,COUNT(*)*1.0/(SELECT COUNT(*)/100 FROM
FROM X
GROUP BY x.Cnt;