我在加载数据时遇到问题。我必须在Oracle数据库中将800,000行从一个表复制到另一个表。
我首先尝试了10,000行但是花费的时间并不令人满意。我尝试使用“BULK COLLECT”和“INSERT INTO SELECT”子句,但对于这两种情况,响应时间大约为35分钟。这不是我正在寻找的理想反应。
有人有任何建议吗?
答案 0 :(得分:5)
Anirban,
使用“INSERT INTO SELECT”是填充表格的最快方法。您可能希望使用以下一个或两个提示来扩展它:
只需在笔记本电脑上使用附加提示,即可在5秒内复制800,000个非常小的行:
SQL> create table one_table (id,name)
2 as
3 select level, 'name' || to_char(level)
4 from dual
5 connect by level <= 800000
6 /
Tabel is aangemaakt.
SQL> create table another_table as select * from one_table where 1=0
2 /
Tabel is aangemaakt.
SQL> select count(*) from another_table
2 /
COUNT(*)
----------
0
1 rij is geselecteerd.
SQL> set timing on
SQL> insert /*+ append */ into another_table select * from one_table
2 /
800000 rijen zijn aangemaakt.
Verstreken: 00:00:04.76
你提到这个操作需要35分钟。你能发布一些更多的细节,所以我们可以看到究竟花了35分钟吗?
此致 罗布。
答案 1 :(得分:1)
我同意罗布。插入()选择是最快的方法。
您到底需要做什么?如果您尝试通过复制到新表然后删除旧表来重命名表,那么最好不要进行表重命名:
alter table
table
rename to
someothertable;
答案 2 :(得分:1)
INSERT INTO SELECT是最快的方法。
如果可能/必要,首先禁用目标表上的所有索引。
如果目标表中没有现有数据,您也可以尝试CREATE AS SELECT。
答案 3 :(得分:0)
如上所述,我建议Insert INTO ... AS select ....
或CREATE TABLE ... AS SELECT ...
作为在两个表之间复制大量数据的最快方法。
您想要在oracle文档中查找直接加载插入。这会在您的语句中添加两个项目:parallel和nologging。重复测试,但执行以下操作:
CREATE TABLE Table2 AS SELECT * FROM Table1 where 1=2;
ALTER TABLE Table2 NOLOGGING;
ALTER TABLE TABLE2 PARALLEL (10);
ALTER TABLE TABLE1 PARALLEL (10);
ALTER SESSION ENABLE PARALLEL DML;
INSERT INTO TABLE2 SELECT * FROM Table 1;
COMMIT;
ALTER TABLE 2 LOGGING:
这将关闭插入到表中的回滚日志记录。如果系统崩溃,则无法恢复,您无法对事务进行回滚。 PARALLEL使用N个工作线程来复制块中的数据。您必须尝试并行工作线程的数量才能在系统上获得最佳结果。
答案 4 :(得分:0)
您要复制的表是否与另一个表的结构相同?它有数据还是您正在创建一个新数据?你能用exp / imp吗? Exp可以提供查询以限制它导出的内容然后导入到db中。您要复制的表的总大小是多少?如果要将大多数数据从一个表复制到一个表,可以使用exp / imp复制整个表,然后删除不需要复制的不需要的行。
答案 5 :(得分:0)
尝试删除目标表上的所有索引/约束,然后在数据加载后重新创建它们。
使用/*+NOLOGGING*/
提示,以防您使用NOARCHIVELOG模式,或者考虑在操作后立即进行备份。