SQL Server 2014上的DECRYPTBYKEY比SQL Server 2012慢

时间:2015-03-17 17:03:28

标签: sql-server encryption sql-server-2012 database-performance sql-server-2014

我们几年来一直在某些SQL Server 2012实例上使用对称密钥进行加密/解密。我们最近安装了一些SQL Server 2014的新实例,并遇到了解密SQL Server 2014安装数据的一些性能问题。

考虑一个如下表格:

CREATE TABLE [dbo].[tblCertTest](
[article_id_enc] [varbinary](100) NOT NULL,
[article_id] [int] NULL
) ON [PRIMARY]

按键和证书创建如下:

CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Passwrrrrd12'

CREATE CERTIFICATE MyCertificateName
WITH SUBJECT = 'A label for this certificate'

CREATE SYMMETRIC KEY MySymmetricKeyName WITH
IDENTITY_VALUE = 'a fairly secure name',
ALGORITHM = AES_256,
KEY_SOURCE = 'a very secure strong password or phrase'
ENCRYPTION BY CERTIFICATE MyCertificateName;

我们的数据集大约有90000行,article_id是一个5位数字。稍微简化一下,article_id_enc使用以下命令加密:

update tblCertTest set article_id_enc = ENCRYPTBYKEY(KEY_GUID('MySymmetricKeyName'),convert(varbinary(100), article_id))

我们已经应用了所有可用的修补程序,我们尝试了不同的SQL Server 2012和SQL Server 2014实例,使用不同的设置,如ssd磁盘,ram磁盘等。

我们在SQL Server和远程上尝试了本地查询。

所有服务器上的执行计划和索引都是相同的。

此SELECT语句在任何SQL Server 2012服务器上大约需要50毫秒,包括简单的开发计算机。在任何SQL Server 2014服务器(包括非常强大的服务器)上,查询至少需要1500毫秒。

OPEN SYMMETRIC KEY MySymmetricKeyName
DECRYPTION BY CERTIFICATE MyCertificateName

SELECT CONVERT(int, DecryptByKey(article_id_enc))
FROM dbo.tblCertTest

有关查询在SQL Server 2014上执行如此糟糕的原因的任何建议吗?有什么改变?

1 个答案:

答案 0 :(得分:9)

  

编辑:我刚刚注意到有一篇知识库文章FIX: A query that uses the DECRYPTBYKEY function takes a long time in SQL Server 2014,但我安装了这篇文章,但它似乎没有改变下面的原始结论。

在运行Windows 10的四核(Intel Core i5-2320)X64桌面计算机上,在SQL Server 2012(11.0.5343.0)和2014(RTM)中运行以下代码。

OPEN SYMMETRIC KEY MySymmetricKeyName DECRYPTION BY CERTIFICATE MyCertificateName;

DECLARE @B VARBINARY(100);

WITH t
     AS (SELECT ROW_NUMBER() OVER (ORDER BY @@SPID) AS article_id
         FROM   sys.all_objects o1,
                sys.all_objects o2,
                sys.all_objects o3,
                sys.all_objects o4)
SELECT @B = ENCRYPTBYKEY(KEY_GUID('MySymmetricKeyName'), CONVERT(VARBINARY(100), article_id))
FROM   t 

在Process Explorer中查看它

2012

enter image description here

2014

enter image description here

有两件事情会立即显现出来。

2012版本使用的CPU较少,并且最大限度地利用了单个核心。 2014版本使用的不仅仅是一个核心,并且具有更多的内核模式活动(红色)

Process Explorer“threads”窗口显示

2012

enter image description here

单个线程正在独占调度程序。

2014

enter image description here

这里的工作由两个线程执行(线程3212正在运行空闲任务sqldk.dll!SOS_Scheduler::Idle)。

跟踪2014进程显示SQL Server和这两个线程遇到大量上下文切换(跟踪时间不同于之前的屏幕截图,因此不同的线程ID)

enter image description here

使用Windows Performance Toolkit跟踪这两个进程显示在不同模块中花费的时间存在一些显着差异

2012

enter image description here

2014

enter image description here

我目前还不确定为什么2014版本会在此视图中报告25%的CPU而在其他视图中报告30%但是无论如何很明显ntoskrnl.exe花费的时间在版本之间显着增加,现在60%时间花在该模块的代码中。执行加密所花费的时间当然会相应减少。

将2012版本的VS代码分析器附加到this和2014 this

所以看起来2014年还有额外的逻辑来阻止调度程序占用,并且它会更频繁地关闭,如下面的附加项所示。

enter image description here

(与2012年相比)

enter image description here

在两个版本中尝试以下操作以执行操作100万次......

SET STATISTICS TIME ON;

DECLARE @B VARBINARY(100);

OPEN SYMMETRIC KEY MySymmetricKeyName DECRYPTION BY CERTIFICATE MyCertificateName;

DBCC SQLPERF("sys.dm_os_wait_stats", CLEAR);

WITH t
     AS (SELECT ROW_NUMBER() OVER (ORDER BY @@SPID) AS article_id
         FROM   master..spt_values v1,
                master..spt_values v2
         WHERE  v1.type = 'P'
                AND v2.type = 'P'
                AND v1.number BETWEEN 1 AND 1000
                AND v2.number BETWEEN 1 AND 1000)
SELECT @B = ENCRYPTBYKEY(KEY_GUID('MySymmetricKeyName'), CONVERT(VARBINARY(100), article_id))
FROM   t

SELECT *
FROM   sys.dm_os_wait_stats
WHERE  wait_type IN ( 'PREEMPTIVE_OS_CRYPTOPS', 'SOS_SCHEDULER_YIELD' ); 

2012(CPU时间= 2344 ms,经过时间= 2383 ms。)

enter image description here

可以清楚地看到,尽管2012年存在PREEMPTIVE_OS_CRYPTOPS等待类型,但在这种情况下不使用它。

相反,它看起来好像查询或多或少地垄断了调度程序(虽然在4毫秒量子结束时仍然自愿屈服 - 4 * 597 = 2388)

2014(CPU时间= 8188 ms,经过时间= 10569 ms。)

enter image description here

2014年,ENCRYPTBYKEY函数的每次调用都会遇到此等待类型,在这种情况下,它(与上下文切换相结合)在整个已用时间上增加了8.2秒。

下面突出显示了一些更耗时的内核调用的调用堆栈。

enter image description here

我还尝试了另一个实验

2014 - SQL Server关联到单CPU

(CPU时间= 4500毫秒,经过时间= 6648毫秒。)

enter image description here

这里的时间安排介于2012年业绩和2014年非关联性能之间,代码在多个不同核心上执行。