12

我正在用 PL/SQL 编写数据转换,用于处理数据并将其加载到表中。根据 PL/SQL Profiler,转换中最慢的部分之一是实际插入到目标表中。该表有一个索引。

为了准备加载数据,我使用表的行类型填充一个变量,然后将其插入到表中,如下所示:

insert into mytable values r_myRow;

似乎我可以通过执行以下操作来获得性能:

  • 在插入期间关闭日志记录
  • 一次插入多条记录

这些方法是否可取?如果是这样,语法是什么?

4

8 回答 8

16

最好一次插入几百行,使用 PL/SQL 表和 FORALL 绑定到插入语句中。有关这方面的详细信息,请参见此处

还要注意如何构造 PL/SQL 表。如果可能的话,宁愿直接在 SQL 中使用“INSERT INTO t1 SELECT ...”进行所有转换,因为在 PL/SQL 中进行逐行操作仍然比 SQL 慢。

无论哪种情况,您也可以通过 using 使用直接路径插入INSERT /*+APPEND*/,这基本上绕过了 DB 缓存,直接将新块分配并写入数据文件。这也可以减少日志记录的数量,具体取决于您如何使用它。这也有一些含义,所以请先阅读精美的手册

最后,如果您要截断并重建表,那么首先删除(或标记为不可用)然后重建索引可能是值得的。

于 2008-09-27T16:28:55.180 回答
2

常规插入语句是在表中获取数据的最慢方法,不适用于批量插入。以下文章引用了许多不同的技术来提高性能:http ://www.dba-oracle.com/oracle_tips_data_load.htm

于 2008-09-27T15:58:38.497 回答
1

删除索引,然后插入行,然后重新创建索引。

于 2008-09-27T15:54:37.027 回答
1

如果删除索引的速度不够快,则需要Oracle SQL*Loader

http://www.oracle.com/technology/products/database/utilities/htdocs/sql_loader_overview.html

于 2008-09-27T15:58:54.690 回答
1

假设您参加了 eid,ename,sal,job。所以首先创建一个表:

SQL>create table tablename(eid number, ename varchar2(20),sal number,job char(10));

现在插入数据:-

SQL>insert into tablename values(&eid,'&ename',&sal,'&job');
于 2012-12-14T22:45:33.997 回答
0

检查此链接 http://www.dba-oracle.com/t_optimize_insert_sql_performance.htm

  1. 您的情况要考虑的要点是使用附加提示,因为这将直接附加到表中,而不是使用 freelist。如果您负担得起关闭日志记录而不是使用带有 nologging 提示的 append 来执行此操作
  2. 使用批量插入而不是在 PL/SQL 中进行迭代
  3. 如果您从文件提要中获取数据,请使用 sqlloaded 将数据直接加载到表中
于 2008-09-27T15:58:15.270 回答
0

这是我对快速插入的建议。

触发器 - 禁用与表关联的任何触发器。插入完成后启用。

索引 - 删除索引并在插入完成后重新创建它。

陈旧的统计信息 - 重新分析表和索引统计信息。

索引碎片整理 - 如果需要,重建索引 使用无日志记录 - 使用 INSERT APPEND 插入(仅限 Oracle)。这种方法是非常危险的方法,不会生成重做日志,因此您不能进行回滚 - 在开始之前备份表并且不要尝试实时表。检查您的数据库是否有类似的选项

并行插入:运行并行插入将更快地完成工作。

使用批量插入约束 - 插入期间开销不大,但仍然是检查的好主意,即使在第 1 步之后它仍然很慢

您可以在http://www.dbarepublic.com/2014/04/slow-insert.html了解更多信息

于 2015-02-04T16:52:39.310 回答
-1

也许您最好的选择之一是实际上尽可能避免使用 Oracle。我自己对此感到困惑,但 Java 进程通常可以胜过许多使用 OCI(阅读:SQL Plus)或会占用您大量时间来正确处理的 Oracle 实用程序(阅读:SQL*Loader )。

这也不会阻止您使用特定的提示(例如 / APPEND /)。

每次我转向这种解决方案时,我都会感到惊喜。

干杯,

罗洛

于 2009-03-19T14:00:33.077 回答