计算整个表的哈希的最快方法

use*_*701 6 sql oracle plsql database-performance oracle12c

我们需要能够为外部环境计算表哈希,并将其与内部环境中的预先计算哈希进行比较.这样做的目的是确保外部环境中的数据不被"流氓"数据库管理员篡改.用户坚持使用此功能.

目前,我们通过计算每列值的个体哈希做到这一点,执行按位异或在列散列得到该行的散列,然后对所有的行执行按位异或哈希拿出的表散列.下面的伪脚本:

cursor hash_cur is
select /*+ PARALLEL(4)*/ dbms_crypto.mac(column1_in_raw_type, HMAC_SH512, string_to_raw('COLUMN1_NAME')) as COLUMN1_NAME
       ...
from TABLE_NAME;

open hash_cur;
fetch hash_cur bulk collect into hashes;
close hash_cur;

for i in 1..hashes.count
loop
  rec := hashes(i);
  record_xor = rec.COLUMN1;
  record_xor = bit_xor(record_xor, rec.COLUMN2);
  ...
  record_xor = bit_xor(record_xor, rec.COLUMNN);

  table_xor = bit_xor(table_xor, record_xor);
end loop;
Run Code Online (Sandbox Code Playgroud)

上面的伪脚本将使用dbms_job并行运行.

问题在于我们为某些表提供了数TB的数据,目前性能无法满足我们想要达到的性能.哈希必须"在运行中"完成,因为用户希望自己执行哈希检查.

  1. 您是否有更好的方法来执行整表散列,或者基本上比较来自不同环境的表,这些表通过低延迟和相对低带宽的网络连接?

在我看来,操作比I/O绑定更多的CPU绑定.我正在考虑将表数据存储在blob中,其中数据按记录正确排列,然后按列排列.然后在输出文件上执行哈希.这应该使操作完全受I/O限制.

  1. 最快的方法是什么?无论如何要在查询的select子句中执行此操作以删除任何开销的PL/SQL到SQL引擎上下文切换?
    • 我正在考虑为此修改一个全局blob
    • 还想删除批量收集结果的I/O开销.

任何可以让我获得更好表现的脚本的建议都将不胜感激.谢谢.

are*_*are 0

您可以使用ORA_HASH并作为表达式传递几列

select sum(ORA_HASH(col1||col2||col3)) as hash from my_table
Run Code Online (Sandbox Code Playgroud)

但在这里,在 AskTom 上,有类似的讨论为什么这不是一个好方法:Creating a unique HASH value for thecontents of a table