分区索引减少缓冲区忙等待?

Partition index to reduce buffer busy waits?

我们的 Oracle 响应时间有时会显着减少一两分钟,而不会产生额外的负载。 我们能够识别出一个插入语句,它会产生大量 buffer busy waits.

从 ADDM 报告中,我们得到以下提示:

Consider partitioning the INDEX "IDX1" with object
ID 4711 in a manner that will evenly distribute concurrent DML across
multiple partitions.

老实说:我不确定那是什么意思。我不知道什么是分区索引。我只能想象这意味着创建一个具有本地索引的分区。

你能帮帮我吗? 对那个 table 的读写频率非常高。没有使用更新或删除。

谢谢, E.

I am not sure what that means.

Oracle 告诉您在索引的很小一部分上有很多并发 ("at the same time") activity。这种情况经常发生。

考虑 table TAB1 上的索引列 TAB1_PK,其值是从序列 TAB1_S 中插入的。假设您有 5 个数据库会话同时插入 TAB1

因为 TAB1_PK 是索引的,并且因为序列是按数字顺序生成值,所以发生的是所有这些会话必须同时读取和更新索引的相同块。

这可能会引起很多争用 -- 方式 比您预期的要多,这是由于索引与多版本读取一致性一起工作的方式。我的意思是,在一些罕见的情况下(取决于事务逻辑的编写方式和并发会话的数量),它确实会造成严重后果。

避免此问题的(真正)旧方法是使用反向键索引。这样,顺序列值就不会全部转到相同的索引块。

然而,这是一把两刃的剑。一方面,你得到更少的争用,因为你在整个索引中插入(好)。另一方面,您的行遍及索引,这意味着您无法缓存它们。您刚刚将一个很大的逻辑 I/O 问题变成了物理 I/O 问题!

如今,我们有了更好的解决方案 -- 索引上的 GLOBAL HASH PARTITION。

使用 GHP,您可以指定哈希桶的数量,并使用它来权衡您需要处理的争用程度与您希望索引更新的紧凑程度(以获得更好的缓冲区缓存)。您使用的索引散列分区越多,您的并发性就越好,但索引块缓冲区缓存也会越差。

我发现 16 左右的(全局散列分区的)数量非常好。