我啥时候应该在 INSERT 期间使用 /*+ APPEND */

Posted

技术标签:

【中文标题】我啥时候应该在 INSERT 期间使用 /*+ APPEND */【英文标题】:When should i use /*+ APPEND */ during INSERT我什么时候应该在 INSERT 期间使用 /*+ APPEND */ 【发布时间】:2019-09-04 10:44:12 【问题描述】:

作为日常导入工作的一部分,我是TRUNCATING 表格数据并从原始文件插入数据。

有些表通常导入较大的数据,例如200,000 行范围内的数据,但有些表导入的数据较少,范围为5,00030,000 行范围内。

对于大表导入,在插入过程中会花费大量时间,最后有时会出现性能问题。

我正在使用 Java 将这个导入处理到 Oracle 表中。所以这个表不是硬编码的,而是根据他们的工作导入的。

jdbcTemplate.execute("TRUNCATE TABLE " + tableName);    --for truncating table

return "INSERT INTO " + tableName + " (" +
                columnData.stream().filter(Objects::nonNull).map(ColumnData::getName).collect(joining(", ")) +
                ", SYSTEM_INSERTED_AT) VALUES (" +
                values.stream().collect(joining(", ")) +
                ", CURRENT_TIMESTAMP)";  --for insertion into table

我想知道在插入过程中使用/*+ APPEND */ 提示是否是个好主意,它是否会提高插入过程中的性能?正如在 oracle 文章中所读到的,为了减少插入,使用 /*+ APPEND */ 并不是一个好主意,因为它最终会影响性能问题。

【问题讨论】:

This website 提示,/*+ APPEND */ 仅适用于 INSERT .. SELECT 语句。那么这对你不起作用 我强烈推荐使用PreparedStatements 而不是这个 我认为在 PL/SQL 过程中使用批量插入来导入 200.000 行会更好。 如果您要再次插入类似的数量,请在 truncate 命令中使用“重用存储” @f1sh 和性能有关系吗? 【参考方案1】:

您的程序几乎肯定不会从APPEND 提示中受益。批处理命令更有可能提高性能。

APPEND 提示在插入 大量 数据时很有帮助。它通过将数据直接写入数据文件并绕过更新内存结构、REDO 和 UNDO 来提高性能。但我们必须愿意接受那些捷径的后果——操作锁定了整个表,数据将无法恢复。

200,000 行不是大量数据。 (除非每一行都包含存储在 LOB 列中的大文件。对于性能问题,谈论字节而不是行通常更有用。)如果我们假设每行有 1,000 字节,那仍然只有 200 兆字节的数据。将 200 兆字节写入内存、UNDO 和 REDO 不会增加超过几秒钟的运行时间。消除这些秒数并没有多大帮助。

批处理是提高程序性能的最佳方式。每个数据库命令都有大量开销,主要用于网络延迟和解析。组合多个命令可以显着降低开销并提高性能。

检查您的数据库 API 或框架是否有批处理选项。启用它可能就像更改配置一样简单。您不需要批量处理所有内容,只需一次合并 100 行即可消除 99% 的开销

如果您没有批处理选项,可以通过连接字符串来构建自己的解决方案。下面的代码演示了在单个命令中插入多行的两种不同方法。

create table table1(a number, b number);

insert into table1
select 1, 1 from dual union all
select 2, 2 from dual;

insert all
    into table1 values(3, 3)
    into table1 values(4, 4)
select * from dual;

【讨论】:

你能举个关于批处理命令的例子,以便我可以尝试检查性能吗? @Andrew 我在答案中添加了两个示例。如果您正在寻找 JDBC 批处理示例,我不是这方面的专家,但网上有很多示例。

以上是关于我啥时候应该在 INSERT 期间使用 /*+ APPEND */的主要内容,如果未能解决你的问题,请参考以下文章

我啥时候应该在 C 中使用 malloc,啥时候不应该?

我啥时候应该使用 FutureBuilder?

我啥时候应该使用 QThread::HighestPriority

Firebase:我啥时候应该使用 refreshToken?

我啥时候应该使用 Vuex?

我啥时候应该使用助手? [关闭]