优化使用ENCRYPT_TDES函数加密的数据的性能

使用ENCRYPT_TDES函数加密通常会降低大多数SQL语句的性能。 解密需要额外的处理,加密数据需要 Db2 中更大的空间。

关于本任务

如果谓词需要解密,则谓词为第二阶段谓词,可能会降低性能。 加密数据也会影响数据库设计,从而间接影响性能。 为了尽量减少性能下降,仅在需要加密时使用加密。

建议 :仅对少数高度敏感的数据元素进行加密,例如信用卡号和病历号。

有些数据值不适合加密。 例如,布尔值和其他小数值集,如1到10之间的整数,不适合加密。 因为很少有值是可能的,所以即使这些数据被加密,也很容易猜到。 在大多数情况下,加密并不是这类数据的安全选项。

在某些情况下,为加密数据创建索引可以提高性能。 加密数据的精确匹配和连接(如果两个表使用相同的加密密钥对相同数据进行加密)可以使用您创建的索引。 由于加密数据是二进制数据,因此加密数据的范围检查需要扫描表空间。 范围检查需要解密一列的所有行值。 因此,应避免检查续航里程,或至少适当调整。

示例:加密性能场景

以下场景包含一系列示例,演示了如何在处理加密数据时提高性能。

示例
假设您必须以加密形式在 EMP 表和 EMPPROJ 表中存储 EMPNO。 要定义加密数据的表和索引,请使用以下语句:

开始通用编程接口信息。

CREATE TABLE EMP (EMPNO VARCHAR(48) FOR BIT DATA, NAME VARCHAR(48));
CREATE TABLE EMPPROJ(EMPNO VARCHAR(48) FOR BIT DATA, PROJECTNAME VARCHAR(48));
CREATE INDEX IXEMPPRJ ON EMPPROJ(EMPNO);
通用编程接口信息结束。
示例
接下来,假设一名员工可以参与多个项目,并且您想将员工和项目数据插入到表中。 要设置加密密码并将数据插入表格,请使用以下语句: 开始通用编程接口信息。
SET ENCRYPTION PASSWORD = :hv_pass;
SELECT INTO :hv_enc_val FROM FINAL TABLE
  (INSERT INTO EMP VALUES (ENCRYPT('A7513'),'Super Prog'));
INSERT INTO EMPPROJ VALUES (:hv_enc_val,'UDDI Project');
INSERT INTO EMPPROJ VALUES (:hv_enc_val,'DB2 10 ');
SELECT INTO :hv_enc_val FROM FINAL TABLE 
  (INSERT INTO EMP VALUES (ENCRYPT('4NF18'),'Novice Prog'));
INSERT INTO EMPPROJ VALUES (:hv_enc_val,'UDDI Project');
通用编程接口信息结束。

您可以通过避免不必要的加密处理重复来提高INSERT语句的性能。 请注意,在SELECT INTO语句中定义了主变量hv_enc_val,然后在后续的INSERT语句中使用。 如果您需要插入大量包含相同加密值的行,可能会发现重复的加密处理会降低性能。 然而,您可以通过加密数据、将加密的数据存储在宿主变量中并插入宿主变量来显著提高性能。

示例
接下来,假设您想找到正在从事UDDI项目的程序员。 请考虑以下SELECT语句:
表现不佳
以下查询显示了如何写出性能良好的查询:

开始通用编程接口信息。

SELECT A.NAME, DECRYPT_CHAR(A.EMPNO) FROM EMP A, EMPPROJECT B
  WHERE DECRYPT_CHAR(A.EMPNO) = DECRYPT_CHAR(B.EMPNO) AND 
        B.PROJECT ='UDDI Project';
通用编程接口信息结束。虽然前面的查询返回了正确的结果,但它解密了 EMP 表中的每个 EMPNO 值和 EMPPROJ 表中 PROJECT = 'UDDI Project' 的每个 EMPNO 值,以执行连接。 对于大型表,这种不必要的解密是一个重大的性能问题
性能良好
以下查询与前面的查询结果相同,但性能明显更好。 要查找正在从事UDDI项目的程序员,请使用以下语句:

开始通用编程接口信息。

SELECT A.NAME, DECRYPT_CHAR(A.EMPNO) FROM EMP A, EMPPROJ B
  WHERE A.EMPNO = B.EMPNO AND B.PROJECT ='UDDI Project';
通用编程接口信息结束。
示例
接下来,假设您想找到员工编号为 A7513 的程序员正在处理的项目。 请考虑以下SELECT语句:
表现不佳
以下查询需要 Db2 解密EMPPROJ表中的每个EMPNO值才能执行连接操作:

开始通用编程接口信息。

SELECT PROJECTNAME FROM EMPPROJ WHERE DECRYPT_CHAR(EMPNO) = 'A7513';
通用编程接口信息结束。
性能良好
以下查询对谓词中的字面值进行加密,以便 Db2 能够将其与存储在EMPNO列中的加密值进行比较,而无需解密整个列。 要查看员工编号为 A7513 的程序员正在处理的项目,请使用以下语句:

开始通用编程接口信息。

SELECT PROJECTNAME FROM EMPPROJ WHERE EMPNO = ENCRYPT('A7513');
通用编程接口信息结束。