Oracle 11g:插入的性能改进

adr*_*ift 8 oracle java

我有一个包含 5 亿行(并且还在增长)的表

我做了以下工作来提高插入的性能:

在数据库端:

  • 删除所有索引和约束
  • 禁用日志记录

在应用方面:

  • 从 JPA 托管实体切换到本机插入查询,向查询添加了 APPEND Oracle 提示
  • 尝试每 1k/2k/3k 行批量提交
  • 尝试并行写入(多线程,线程数=服务器上的核心数)到一张表

这给了我大约每秒 300 行

另外试过:

  • 批量并行写入多个表(使用 UNION 分组然后返回结果)

这给了我每秒大约 1k 行,但在空表上。但是当我用虚拟数据(每个表 200 万)填充表时,插入速度下降到每秒 250 - 300 次。

谁能建议我还能做些什么来加速插入?基本上我想首先了解什么是(可能是什么)瓶颈。

UPD: 表按插入日期分区,表有大约 60 列 - 大多数列是 VARCHAR2(2000 BYTE)

Riy*_*lla 5

刚刚看到更新的 60 列表,其中大部分是 VARCHAR(2k) 字段——也就是说(可能)是一个怪物表。

首先要...

你必须首先了解你的瓶颈。在应用程序方面,一直回到您的单线程批量插入解决方案(一次 1/2/3k)并开始运行它并登录到数据库机器并运行“顶部”——看看有多少数据库进程花费的时间以及机器显示的时间(如果有)wa%。

如果 top 向您显示任何 wa% 时间,则意味着您的数据库受 I/O 限制,您可能需要考虑多台数据库机器(分片)或考虑在主机上放置 SSD。

就是这样; 你的研究到此为止。数据库占用多少 CPU 或您的应用程序客户端有多饱和都无关紧要;如果您在主机 DB 上遇到 I/O 延迟问题,那么它会尽可能快地为您解决问题。

提示如果硬件更改是不可能的,根据您正在运行的文件系统 (Linux),您可以尝试禁用数据库的日志记录或元数据写入,以稍微提高文件系统级别的性能。您可以在 NTFS 上做类似的事情,但这只会给您带来一点提升。这不会是 2 倍。

现在,第二件事...

假设您几乎没有 wa% 时间,但您的 CPU 已完全被 DB 进程占用。您现在唯一的选择是引入更多数据库机器(分片)并分工。

同样,如果是这种情况,您的研究就完成了。您无法调整 CPU 以使其运行得更快。

最后,第三件事……第三……

假设数据库没有做任何事情。然后,转到运行批量插入的客户端机器并检查 CPU 负载——它是否被挂钩?如果是这样,请启动更多机器执行完全相同的批量插入,看看是否可以获得线性斜坡。

如果 CPU 未挂钩,请在同一台机器上启动更多线程,直到它挂钩并查看数据库如何扩展。

我想您可能已经尝试过,所以我的猜测是您的客户端主机已经被挂钩(并且更多的线程不会产生影响)或者数据库已经达到其限制并且无法进一步扩展。

附录

在一个没有垃圾的未索引表上进行原始插入本质上是一个 APPEND 操作,它应该与磁盘处理写入的速度一样快。

在同一台主机上创建更多表不会有帮助,如果有的话它会增加您的磁盘搜索(以获取磁盘上的其他表以附加到)并且会减慢速度。

首先找出瓶颈至关重要,然后我们可以优化它。

希望有帮助!随时关注我们。

  • 你为什么没有提到awr或statspack? (2认同)