2

直到几天前,我们在 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%) 似乎相关的峰值。

知道这里可能发生了什么变化吗?或者关于我们如何获得更可预测的性能的其他想法?谢谢你。

4

0 回答 0