36 个字符的主键不应该成为真正减慢插入行的问题。使用具有唯一值的索引强制执行主键。 36 个字符加上一些开销加上使用 AL32UTF8 时的额外内容,仍然允许 8 KB 块大小在一个索引叶块中容纳许多值。
可能还有其他事情发生。
请定义:
- 150 M 行的平均行长。
- 慢的定义
- 在加载多少行之后,它在什么时候变慢。
- 如何加载(SQL*Loader?SQL?自己的代码?线程?)
- 准确的 Oracle 版本(从 v$version 中选择 *)
删除索引有帮助
从补充中我了解到,在唯一指标(PK指标)下降后,性能是合理的(22K/s)。
您可能需要检查以下内容:
- 检查 PowerCenter 正在使用什么后端,这取决于 ETL 作业、版本和平台的可能性。也许是插入/选择,并行是/否,甚至是提取和重新加载。为简单起见,我们假设它是一些并行选择和插入。
- 11.2.0.3 是一个很好的 Oracle 版本,几乎没有令人讨厌的错误。
- 根据 DBA 配置空间管理的方式,查看 PK 索引的 initrans 和 maxtrans。第一个确定允许活动的事务数。例如,将 initrans 设置为并发插入的数量。
- 检查数据字典上的统计信息是否完全不存在或最新(在 dba_tables 中查找实例)。
- 检查您自己的表上的统计信息是否缺失或相当准确(更改表 xxx 计算所有索引的所有列的表的统计信息)。在加载的数据量和/或分布发生重大变化后重复此步骤。
- 有时,尤其是在初始加载时,索引可能会变得过于碎片化。也许为 UUID 生成的值对此有所贡献。使用查询可以检测到这一点,但要保持简单:始终在初始加载表后重建索引。随着时间的推移,变化变得越来越小,从 1 行变为 1.000.000 是一个很大的变化,从 100 万变为 200 万则不是。您现在应该只需要这样做一次。
附带说明:以 36 个字符的列作为主键的一行 60 个字符似乎不切实际。每个 ID 大约需要精度 / 2 + 1 个字节(BCD 格式)。但即使行大小翻倍,也不会产生重大影响。
检测受益于重建的索引
根据要求添加:
我使用以下查询来确定符合重建条件的索引。最后的标准可以更改。对于 OLTP 环境中的生产使用,它们足以充分减少不必要的消息,但仍能检测到真正的坏情况。以特权用户身份运行或授予对相关数据字典视图的读取权限。应在 Oracle 8、8i、9 和 10 上运行。最近未在 11 或 12 上使用。
我知道直接查询数据字典并不总是可取的,例如在使用数据模型的多个版本时,但这样做的效果要好得多。受益于重建的索引可以通过存储受益(在黑暗时代,我们在 VMS 服务器上只有几 MB,每个 KB 都很有价值),有时还可以提高性能。
ttitle "Warning: Fragmented Indexes (&dbname)" -
skip 2 "Corrective action:" -
skip 1 "Rebuild index (rebuildIndexes.sql)." -
skip 2
column owner format a30 heading "Owner"
column ind_name format a30 heading "Index"
column num_rows format 999,999,990 heading "#Rows"
column cur_size_kb format 9,999,990 heading "Current Size (Kb)"
column est_size_kb format 9,999,990 heading "Est. Size (Kb)"
column ratio format 9,990 heading "Ratio cur/est"
select /*+ rule */ usr.name owner
, objind.name ind_name
, round
(
( sum
( (tab.rowcnt - head.null_cnt) * col.length * 0.5
/* 50% average fill */
)
* 1.5 /* 75% usage after some delet/update */
+ 5 * ts.blocksize
) /1024
) est_size_kb
, round(ts.blocksize * seg.blocks / 1024) cur_size_kb
, round
( ts.blocksize * seg.blocks
/ ( sum((tab.rowcnt - head.null_cnt) * col.length * 0.5) * 1.5
+ 5 * ts.blocksize
)
) ratio
, tab.rowcnt num_rows
from sys.ind$ ind
, sys.hist_head$ head
, sys.col$ col
, sys.icol$ icol
, sys.obj$ objind
, sys.obj$ objtab
, sys.tab$ tab
, sys.ts$ ts
, sys.seg$ seg
, sys.user$ usr
where 1=1
and ts.ts# = seg.ts#
and seg.file# = ind.file#
and seg.block# = ind.block#
and ind.obj# = objind.obj#
and head.col# (+) = col.col#
and head.obj# (+) = col.obj#
and icol.obj# = ind.obj#
and col.col# = icol.col#
and col.obj# = objtab.obj#
/* To save at least 25 Mb, the index must be over 25 Mb. */
and ts.blocksize * seg.blocks > 25 * 1024
and ind.bo# = objtab.obj#
and objind.obj# = ind.obj#
and tab.obj# = objtab.obj#
and objtab.owner# = usr.user#
and usr.name not in ('SYS','SYSTEM')
group
by objind.name
, ts.blocksize
, seg.blocks
, tab.rowcnt
, usr.name
having ts.blocksize * seg.blocks / ( sum((tab.rowcnt - head.null_cnt) * col.length * 0.5) * 1.5 + 5 * ts.blocksize )
>= 2
and ( ts.blocksize * seg.blocks / 1024 )
-
( sum((tab.rowcnt - head.null_cnt) * col.length * 0.5) * 1.5
+ 5 * ts.blocksize
) / 1024
> 25 * 1024
order by 5 desc