您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

在10分钟内在Oracle中插入1千万个查询?

在10分钟内在Oracle中插入1千万个查询?

我知道其他人已经提到了这一点,但是您不想听到它,而是使用SQL*Loader外部表。对于略多于10m的行,我对大约相同宽度的表的平均加载时间为12.57@H_502_1@秒 。这些实用程序经过明确设计,可以将数据快速加载到数据库中,并且非常擅长。根据输入文件的格式,这可能会导致一些额外的时间损失,但是有很多选择,而且在加载之前,我很少需要更改文件

如果您不愿意这样做,则不必升级硬件。您需要消除所有可能的障碍以快速加载该文件。要枚举它们,请删除

有了所有这些,您就必须让数据库执行更多的工作,并且由于要以事务方式进行此操作,因此您并未充分利用数据库的潜力。

将数据加载到一个单独的表中,例如ABC_LOAD。该数据已被完全加载后进行 @H_502_1@单一的 INSERT语句为ABC。

insert into abc
select abc_seq.nextval, a.*
  from abc_load a

当您执行此操作时(即使您不这样做),请确保序列缓存大小正确;否则,请执行以下步骤。引用

当应用程序访问序列缓存中的序列时,可以快速读取序列号。但是,如果应用程序访问不在缓存中的序列,则在使用序列号之前,必须将该序列从磁盘读取到缓存。

如果您的应用程序同时使用许多序列,则序列缓存可能不足以容纳所有序列。在这种情况下,访问序列号通常可能需要读取磁盘。为了快速访问所有序列,请确保您的缓存中有足够的条目来保存应用程序并发使用的所有序列。

这意味着,如果您有10个线程使用此序列同时写入500条记录,那么您需要的缓存大小为5,000。在ALTER SEQUENCE文件指出如何改变这样的:

alter sequence abc_seq cache 5000

如果您按照我的建议,我会将缓存大小提高到10.5m左右。

查看使用APPEND提示(另请参见Oracle Base);这指示Oracle使用直接路径插入,该插入将数据直接附加到表的末尾,而不是寻找放置它的空间。如果您的表有索引,则将无法使用它,但是您可以在其中使用它ABC_LOAD

insert /*+ append */ into ABC (SSM_ID, invocation_id , calc_id, ... )
select 'c','b',NULL, 'test', 123 , 'N', 'asdf' from dual
union all select 'a','b',NULL, 'test', 123 , 'N', 'asdf' from dual
union all select 'b','b',NULL, 'test', 123 , 'N', 'asdf' from dual
union all select 'c','g',NULL, 'test', 123 , 'N', 'asdf' from dual

如果使用APPEND提示;插入后,我将添加TRUNCATEABC_LOADABC否则此表将无限期增长。这将是安全的,因为届时您将完成使用该表的操作。

您没有提到您使用的是哪个版本或Oracle。您可以使用许多额外的小技巧:

这个版本支持身份列; 您可以完全摆脱顺序。

    CREATE TABLE ABC(
   seq_no         NUMBER GENERATED AS IDENTITY (increment by 5000)

如果保持触发;您可以直接分配序列值。

    :new.seq_no := ABC_seq.nextval;

如果您使用的是Oracle Enterprise,则可以ABC_LOAD使用PARALLEL提示来加快INSERT的速度:

    insert /*+ parallel */ into abc
select abc_seq.nextval, a.*
  from abc_load a

这可能会导致自身的问题(太多并行进程等),因此请进行测试。这对于较小的批处理插入 @H_502_1@可能会 有所帮助,但不太可能,因为您将浪费时间计算哪个线程应该处理什么。

使用数据库随附的实用程序。

如果您不能使用它们,那么请摆脱所有可能减慢插入速度并批量进行插入操作的原因,因为这正是数据库的优势所在。

Oracle 2022/1/1 18:44:27 有439人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶