DBMS_CRYPTO性能问题

时间:2012-01-25 02:22:36

标签: performance encryption indexing oracle10g

我正在使用DBMS_CRYPTO来保护数据库泄露时的信息。密钥不存储在dbms中,而是由应用程序在每次访问时提供。

select decrypt(name), seq order by seq查询(几乎完全)比任何一个

长15倍
select decrypt(name), seq

select name, seq order by seq

这让我相信解密功能正在打破主键seq上的索引。它为什么会破裂?

我尝试将关键字DETERMINISTIC添加到函数的输出类型中,但它只将时间缩短到快速查询的10倍左右。我不明白为什么它应该比select decrypt(name), seq更长。 修改DETERMINISTIC关键字也加快了简单的解密查询,应该是预期的。

我的期望是错的,还是别的?考虑到我已经给出的安全限制,我有300毫秒的延迟,但3000毫秒是明显的,我想让它更快。

我正在使用名为SmartSQL的数据库工具,它提供了“经过时间”的显示(我假设在发送查询和接收结果的最后一位之间的时间)。

seq上有一个索引,即主键。我想要在加密值上放置索引无济于事。

执行计划:

选择decrypt(name),seq

------------------------------------------------------------------------------------
| Id  | Operation         | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                |  8810 |  1453K|    98   (3)| 00:00:02 |
|   1 |  TABLE ACCESS FULL| CSTN_MEMB_INFO |  8810 |  1453K|    98   (3)| 00:00:02 |
------------------------------------------------------------------------------------

通过seq desc选择名称,seq顺序

---------------------------------------------------------------------------------------------
| Id  | Operation          | Name           | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                |  8810 |  1453K|       |   428   (1)| 00:00:06 |
|   1 |  SORT ORDER BY     |                |  8810 |  1453K|  3448K|   428   (1)| 00:00:06 |
|   2 |   TABLE ACCESS FULL| CSTN_MEMB_INFO |  8810 |  1453K|       |    98   (3)| 00:00:02 |
---------------------------------------------------------------------------------------------

选择解密(名称),按seq desc

选择顺序
---------------------------------------------------------------------------------------------
| Id  | Operation          | Name           | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                |  8810 |  1453K|       |   428   (1)| 00:00:06 |
|   1 |  SORT ORDER BY     |                |  8810 |  1453K|  3448K|   428   (1)| 00:00:06 |
|   2 |   TABLE ACCESS FULL| CSTN_MEMB_INFO |  8810 |  1453K|       |    98   (3)| 00:00:02 |
---------------------------------------------------------------------------------------------

我的完整查询如下所示:

select 
    seq, gender, wdate, address, 
    my_crypto_pkg.decrypt(tel, 'my_secret_key'), 
    my_crypto_pkg.decrypt(name, 'my_secret_key') 
from cstn_memb_info
--  where my_crypto_pkg.decrypt(name, 'my_secret_key') like ?
order by
    seq desc

1 个答案:

答案 0 :(得分:3)

只要涉及解密数据的谓词被注释掉,返回第一行的时间对于三个查询将是非常不同的。但考虑到你想要达到的最终结果,这似乎没有意义。

如果你取消decrypt调用,那么你只是扫描表而不必调用单独的函数来解密数据(这比仅仅读取它要贵得多) 。如果消除ORDER BY,Oracle只需要在返回数据之前解密前N行,甚至不必完成扫描表。如果解密数据并对结果进行排序,则必须在排序发生之前解密所有数据,并且可以开始返回结果。对于同时执行decryptORDER BY的查询,获取最后一行的时间也是最长的,但差异将不那么显着。一旦在解密值上添加了谓词,所有查询应该至少与三个查询中最慢的查询一样慢,这与您最终想要运行的查询更加一致。

实际上,由于您打算对解密值进行谓词,并且由于加密密钥是在运行时传入的,因此在您订购之前,您将不得不对表进行全面扫描,解密每一行。结果。随着数据量的增加,这将非常缓慢。当你谈到“分页视图”时,它通常也与你所描述的内容不兼容。由于每次运行此查询时都必须解密每一行,因此您不希望编写返回前10行的查询,然后发出另一个查询以获取行11-20,依此类推。每次获取一页数据时,都需要重新解密表中的每一行。

如果您使用的是11g,则使用结果缓存功能可能会允许您发出单独的查询,以便以合理有效的方式获取单个数据页面。但这在10g中是不可用的。