暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 优化阅读

askTom 2017-03-13
147

问题描述

嗨,
让我描述一下我的情况:
我正在使用Oracle 11g实例来模拟一些敏感数据 (16个字符的字符串)。
Oracle表结构如下:
哈希 (32字节) | ENC (32字节) | IMP (16字节)
美国广播公司113abc... | PKn5ez... | abcdefghijklmnop

应用程序获取敏感字符串,对其进行哈希处理,并将此哈希请求到DB表中。
如果这个散列不存在:
(1) 它计算加密值 (ENC),模拟值 (IMP) 并在表中添加新行
如果这个散列存在:
(2) 它从表中返回IMP值
(ENC值仅用于反向过程,超出此处的范围)。

几天后,此表可以容纳20m行,并且很可能会出现新的敏感字符串。因此,将运行的是男子气概的项目 (2)。
开始时,它非常快 (〜4000模拟/s),但是当表有15m行时,它将达到300/s。逻辑as Oracle现在必须检查表中是否存在给定的哈希,只要它必须搜索更多条目,它显然会变慢。
当然,这个表在哈希列上有索引; 但是,当添加行时,我可以清楚地看到这种模拟/s的数量急剧下降。
有没有办法衡量这个指数的表现?
我对这个索引有一些疑问,因为它运行一个简单的SQL命令,比如:
从表中选择IMP,其中HASH = 'BA8699FB16981ECD4631AE8FC64561DC3810E85CED892EE3A3B9450184CF368';
需要12秒才能完成,即使下一个相同的请求也需要相同的时间。

主要问题是: 如何使这一过程更有效率?

有了15m的条目,我可以看到像15mb/s这样的I/O作为读取 (没有写入作为哈希很可能存在于表中,所以没有创建)。
可能可以以某种最佳方式设置Oracle缓存,但我不知道在这里要更改什么。
磁盘上的表大小小于10gb,我的第一个想法是将此表加载到内存中,以在查找哈希时避免这些I/o。

有人能帮忙吗?
谢谢,
吉恩

专家解答

你需要给我们一个测试用例,向我们展示为什么事情进展缓慢。这是我的演示

--
-- target table
--
SQL> create table t (
  2    h varchar2(32),
  3    e varchar2(32),
  4    i varchar2(32)
  5  );

Table created.

--
-- 10million random hashes
--
SQL>
SQL> insert /*+ APPEND */ into t
  2  with inputs as
  3  (
  4    select x1*x2 val
  5    from
  6      ( select dbms_random.value(1,10000) x1 from dual connect by level <= 10000 ),
  7      ( select dbms_random.value(1,10000) x2 from dual connect by level <= 1000 )
  8  )
  9  select
 10    to_char(ora_hash(val),'xxxxxxxxxxxxxxxx'),
 11    to_char(ora_hash(val),'xxxxxxxxxxxxxxxx'),
 12    to_char(trunc(val))
 13  from inputs;

10000000 rows created.

--
-- index on hash col
--
SQL>
SQL> create index t_ix on t ( h );

Index created.

--
-- I'll pick 10,000 random values from the table
-- and store them in an array.  They will be used to simulate
-- queryies using them
--
SQL> create table source_feed as select h
  2    from ( select h from t order by dbms_random.value )
  3    where rownum <= 10000;

Table created.

--
-- So now I do 10,000 hash val lookups
--
SQL> set serverout on
SQL> declare
  2    r pls_integer;
  3    n sys.odcivarchar2list := sys.odcivarchar2list();
  4    s timestamp;
  5    tot pls_integer := 0;
  6  begin
  7    select h bulk collect into n from source_feed;
  8
  9    s := systimestamp;
 10    for i in 1 .. n.count loop
 11      select count(i)
 12      into r
 13      from t
 14      where h = n(i);
 15
 16      tot := tot + r;
 17    end loop;
 18    dbms_output.put_line(systimestamp-s);
 19    dbms_output.put_line('tot='||tot);
 20  end;
 21  /
+000000000 00:00:01.125000000
tot=10023


这大约是每秒9k的查找 (在我的笔记本电脑上)。

索引查找非常快,即,实际上仅取决于I/O系统的速度以及内存中可以存储多少
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论