我正在PL / SQL中编写一个数据转换来处理数据并将其加载到表中。根据PL / SQL Profiler,转换中最慢的部分之一是实际插入目标表。该表有一个索引。
要准备加载数据,我使用表的rowtype填充变量,然后将其插入表中,如下所示:
insert into mytable values r_myRow;
似乎我可以通过以下方式获得表现:
这些方法是否可取?如果是这样,语法是什么?
答案 0 :(得分:16)
最好一次插入几百行,使用PL / SQL表和FORALL绑定到insert语句中。有关详细信息,请参阅here。
还要小心如何构造PL / SQL表。如果可能的话,更喜欢使用“INSERT INTO t1 SELECT ...”直接在SQL中完成所有转换,因为在PL / SQL中逐行操作仍然比SQL慢。
在任何一种情况下,您也可以使用INSERT /*+APPEND*/
来使用直接路径插入,{{1}}基本上绕过数据库缓存并直接为数据文件分配和写入新块。这也可以减少日志记录量,具体取决于您使用它的方式。这也有一些影响,所以请先阅读fine manual。
最后,如果要截断并重建表,则首先删除(或标记不可用)并稍后重建索引可能是值得的。
答案 1 :(得分:2)
常规插入语句是在表中获取数据的最慢方式,而不是用于批量插入。以下文章引用了许多用于提高性能的不同技术:http://www.dba-oracle.com/oracle_tips_data_load.htm
答案 2 :(得分:1)
如果删除索引并不能加快速度,则需要 Oracle SQL * Loader :
http://www.oracle.com/technology/products/database/utilities/htdocs/sql_loader_overview.html
答案 3 :(得分: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');
答案 4 :(得分:0)
删除索引,然后插入行,然后重新创建索引。
答案 5 :(得分:0)
检查此链接 http://www.dba-oracle.com/t_optimize_insert_sql_performance.htm
答案 6 :(得分:0)
也许您最好的选择之一就是尽可能避免使用Oracle。 我自己一直对此感到困惑,但是Java流程通常可以胜过许多使用OCI(读取:SQL Plus)的Oracle实用程序,或者占用大量时间来实现正确(读取:SQL * Loader) )。
这并不妨碍您使用特定提示(例如/ APPEND /)。
每次我转向那种解决方案时,我都感到惊喜。
干杯,
罗洛梅
答案 7 :(得分:0)
以下是我对快速插入的建议。
触发器 - 禁用与表关联的任何触发器。插入完成后启用。
索引 - 删除索引并在插入完成后重新创建它。
陈旧统计 - 重新分析表和索引统计信息。
索引碎片化 - 如果需要,重建索引 使用INSERT APPEND使用No Logging -Insert(仅限Oracle)。这种方法是非常危险的方法,不会生成重做日志,因此您无法进行回滚 - 在开始之前备份表并且不尝试实时表。检查您的数据库是否有类似的选项
并行插入:运行并行插入可以更快地完成工作。
使用批量插入 约束 - 在插入过程中没有太大的开销但是仍然是一个好主意检查,如果在第1步之后它仍然很慢
上了解详情