直到几天前,我们在 SQL Azure 中运行的 T-SQL 代码为临时表值生成 MD5 速度很快(在 Business Critical Gen 5, 2 VCores DB 上每十万秒几秒)。最近,我们从日志中注意到,在多个客户端数据库和我们的测试中,存在巨大的差异,导致频繁超时。这是生成 MD5 和 SHA2 的示例代码(尽管 MD5 是我们的生产要求)。
begin transaction;
/********************************/
-- create temp table
/********************************/
CREATE TABLE #tmp (
Id int PRIMARY KEY,
UriValue nvarchar(256),
Md5Value binary(16)
);
/********************************/
-- generate 1 million records into temp table
-- source: https://dba.stackexchange.com/questions/130392/generate-and-insert-1-million-rows-into-simple-table
/********************************/
WITH
L0 AS (SELECT c FROM (SELECT 1 UNION ALL SELECT 1) AS D(c)), -- 2^1
L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B), -- 2^2
L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B), -- 2^4
L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B), -- 2^8
L4 AS (SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B), -- 2^16
L5 AS (SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B), -- 2^32
Nums AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS k FROM L5
)
INSERT INTO #tmp ( Id, UriValue )
SELECT k as Id,
'http://sample.com/' + CONVERT(nvarchar(50), NEWID()) as UriValue
FROM nums
WHERE k <= 100000
/********************************/
-- test creation of SHA2 value
/********************************/
DECLARE @dt datetime; -- timer
SET @dt = GETUTCDATE();
UPDATE #tmp
SET Md5Value = CAST(HashBytes('SHA2_256', CONVERT(VARCHAR(MAX), LOWER(UriValue)) COLLATE Latin1_General_100_CI_AS_SC_UTF8) as binary(16));
SELECT DATEDIFF(ms, @dt, GETUTCDATE()) AS Sha2ElapsedMs;
/********************************/
-- test creation of MD5 value
-- note: our requirement is for a match to http://md5-hash-online.waraxe.us/
/********************************/
SET @dt = GETUTCDATE();
UPDATE #tmp
SET Md5Value = CAST(HashBytes('MD5', CONVERT(VARCHAR(MAX), LOWER(UriValue)) COLLATE Latin1_General_100_CI_AS_SC_UTF8) as binary(16));
SELECT DATEDIFF(ms, @dt, GETUTCDATE()) AS Md5ElapsedMs;
rollback transaction;
注意使用 NEWID() 来生成 GUID,所以我不认为缓存是我们测试中的问题。
以下是一些测试运行: Run 1:SHA2 45 秒,MD5 39 秒 Run 2:SHA2 4 秒,MD5 3 秒 Run 3:SHA2 34 秒,MD5 38 秒 Run 4:SHA2 9 秒,MD5 9 秒
在这些测试期间,没有其他进程正在针对数据库运行。我在 Azure 门户中看到 CPU (90%) 和 SQL Server 进程 (99%) 似乎相关的峰值。
知道这里可能发生了什么变化吗?或者关于我们如何获得更可预测的性能的其他想法?谢谢你。