我正在使用DBMS_CRYPTO来保护数据库泄露时的信息。密钥不存储在dbms中,而是由应用程序在每次访问时提供。
select decrypt(name), seq order by seq
查询(几乎完全)比任何一个
select decrypt(name), seq
或
select name, seq order by seq
这让我相信解密功能正在打破主键seq
上的索引。它为什么会破裂?
我尝试将关键字DETERMINISTIC
添加到函数的输出类型中,但它只将时间缩短到快速查询的10倍左右。我不明白为什么它应该比select decrypt(name), seq
更长。 修改:DETERMINISTIC
关键字也加快了简单的解密查询,应该是预期的。
我的期望是错的,还是别的?考虑到我已经给出的安全限制,我有300毫秒的延迟,但3000毫秒是明显的,我想让它更快。
我正在使用名为SmartSQL的数据库工具,它提供了“经过时间”的显示(我假设在发送查询和接收结果的最后一位之间的时间)。
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 |
------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
| 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 |
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
| 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
答案 0 :(得分:3)
只要涉及解密数据的谓词被注释掉,返回第一行的时间对于三个查询将是非常不同的。但考虑到你想要达到的最终结果,这似乎没有意义。
如果你取消decrypt
调用,那么你只是扫描表而不必调用单独的函数来解密数据(这比仅仅读取它要贵得多) 。如果消除ORDER BY
,Oracle只需要在返回数据之前解密前N行,甚至不必完成扫描表。如果解密数据并对结果进行排序,则必须在排序发生之前解密所有数据,并且可以开始返回结果。对于同时执行decrypt
和ORDER BY
的查询,获取最后一行的时间也是最长的,但差异将不那么显着。一旦在解密值上添加了谓词,所有查询应该至少与三个查询中最慢的查询一样慢,这与您最终想要运行的查询更加一致。
实际上,由于您打算对解密值进行谓词,并且由于加密密钥是在运行时传入的,因此在您订购之前,您将不得不对表进行全面扫描,解密每一行。结果。随着数据量的增加,这将非常缓慢。当你谈到“分页视图”时,它通常也与你所描述的内容不兼容。由于每次运行此查询时都必须解密每一行,因此您不希望编写返回前10行的查询,然后发出另一个查询以获取行11-20,依此类推。每次获取一页数据时,都需要重新解密表中的每一行。
如果您使用的是11g,则使用结果缓存功能可能会允许您发出单独的查询,以便以合理有效的方式获取单个数据页面。但这在10g中是不可用的。