我们的应用程序管理一个表,其中包含每个用户的一组行,这是计算密集型查询的结果 。将此结果存储在表 中似乎是加速进一步计算的好方法。在具有索引结构的大型表格上改进DELETE和INSERT时间
该表的结构基本上与以下:
CREATE TABLE per_user_result_set
(user_login VARCHAR2(N)
, result_set_item_id VARCHAR2(M)
, CONSTRAINT result_set_pk PRIMARY KEY(user_login, result_set_item_id)
)
;
我们的应用程序将具有这个结果集计算的 每天30次,用1个单品和之间组成的一个结果集的典型的用户500,000个项目。 典型的客户将向生产数据库申报约500名用户。 所以,这张表通常由500万行组成。
,我们用它来更新此表中的典型查询:
BEGIN
DELETE FROM per_user_result_set WHERE user_login = :x;
INSERT INTO per_user_result_set(...) SELECT :x, ... FROM ...;
END;
/
已经遇到性能问题(DELETE部分将花费更多的时间) 我们决定全局临时表后(上提交删除行)持有行的 “增量”从表和行压制插入到它:
BEGIN
INSERT INTO _tmp
SELECT ... FROM ...
MINUS SELECT result_set_item_id
FROM per_user_result_set
WHERE user_login = :x;
DELETE FROM per_user_result_set
WHERE user_login = :x
AND result_set_item_id NOT IN (SELECT result_set_item_id
FROM _tmp
);
INSERT INTO per_user_result_set
SELECT :x, result_set_item_id
FROM _tmp;
COMMIT;
END;
/
这提高了性能一点,但是这仍然不尽如人意。所以 我们正设法加速这一进程,这里是 我们遇到的问题:
- 我们会喜欢使用表分区(由USER_LOGIN分区)。 但分区并不总是可用的(在我们的测试数据库中,我们打到了 ORA-00439)。我们的客户无法承担支付额外功能的Oracle企业版 。
- 我们可以使
per_user_result_set
表全局临时使其 是孤立的,我们可以TRUNCATE
它例如...但我们的应用程序 有时丢失是由于网络问题连接到Oracle,并会 自动重新连接。那时我们失去了我们的计算内容 。 - 我们可以将该表拆分成一定数量的存储桶,制作一个视图 联合会所有这些存储桶,并触发INSTEAD OF UPDATE和DELETE 该视图,并根据
ORA_HASH(user_login) % num_buckets
重新分配行。 但是我们担心这可能会让SELECT
操作变得更慢。 这会导致表的数量不变,在DELETE或INSERT操作中影响较小的索引 。总之,“ 穷人分区表”。 - 我们试过
ALTER TABLE per_user_result_set NOLOGGING
。这不是 改善很多东西。 - 我们试过
CREATE TABLE ... ORGANIZATION INDEX COMPRESS 1
。这加快了 东西的比例为1:5。 - 我们试图为每个user_login设置一个表。这正是我们通过使用与不同的user_logins和精心挑选的散列函数相同数量的分区进行分区而得到的结果 。性能因子是 1:10。但我真的想避免这个解决方案:必须保持一个 大量的索引,表,视图,在每个用户的基础上。这将是 一个有趣的性能增益为用户,但不是我们这个系统的维护者 。
- 由于用户同时工作,我们无法创建新的 表并将其与旧的交换。
你能提出什么建议补充这些方法?
注意。我们的客户将Oracle数据库从9i升级到11g,并将XE版本升级到 企业版。这是多种版本,我们需要与 兼容。
谢谢。
我首先想到的是使表的IOT,但你已经做到了,这导致了5倍加速,是正确的? 我能想到的唯一的其他事情就是避免删除。不管怎样,每次运行新查询时都要使用一个序列使旧结果集老化 - 即表变为user_login,result_set_id和result_set_item_id。您可能需要跟踪users表中的最新result_set_id或其他内容。 您是否100%肯定插入/删除是问题,而慢速部分找不到result_set_item_id? – 2012-02-27 13:57:01
@Stephen ODonnell:我相信大部分时间都在'DELETE'部分。 – Benoit 2012-02-27 14:09:36
到目前为止,您已经完成了哪些工作来收集详细的跟踪数据?我们可以猜测所有我们想要的解决方案,但是您需要数据才能真正找出问题并加以解决。乔纳森刘易斯的书“基于成本的Oracle基础知识”将是一个很好的起点。 – 2012-02-27 14:33:47