2011-04-06 148 views
2

我有几种服务在处理不同的输入文件格式(XML,平面文件等)后将数据转储到数据库(oracle)。我想知道是否可以让它们生成SQL语句并将它们记录到某个文件系统,并拥有一个SQL处理器(类似java hibernet),它将处理这些SQL文件并上传到数据库。 执行大量SQL语句(遍布文件系统,由多个编写者编写)到oracle数据库中的最快方式是什么?我正在考虑分配数据库和批量更新。但是,我想知道这里的最佳做法。似乎这是一个常见问题,有人必须已经面对/解决了这个问题。 谢谢 Atanu高性能数据库更新(oracle)

回答

1

如果你想要最大的性能,你不想吨的SQL语句。请看看Oracle Data Pump。

并且不要对平面文件进行任何预处理。而是直接将它们提供给impdp(Oracle Data Pump Importer)。

如果导入数据需要转换,更新等,那么最佳做法是将数据加载到临时表(使用数据泵),对暂存表执行一些预处理,然后将数据合并到生产表中。

数据库外部的预处理通常非常有限,因为您无法访问已加载的数据。所以你甚至不能检查记录是新的还是现有的更新。

+2

DataPump使用Oracle专有格式,所以它在这里似乎不是一个解决方案。问题是关于从不同的系统/格式加载数据。 DataPump都是关于在Oracle数据库之间交换数据的。 – APC 2011-04-06 21:10:49

+0

我可能会对Oracle的数据泵和装载程序命名感到困惑。我参考了最初被称为SQL * Loader的工具。它们支持文本文件的高性能加载。也许它仍然被称为SQL * Loader,即使通过外部表使用它。 – Codo 2011-04-07 12:34:26

5

atanu, 要做的最糟糕的事情就是生成巨大的插入语句列表。如果你想加快速度,并且知道数据的布局,可以使用外部表将数据加载到oracle数据库中。这看起来很像使用sql * loader,但是可以使用表访问数据。在表定义中,您的数据字段将映射到您的列名称和数据类型。 这将是批量加载到数据库中的最快方式,确实如此。

有关文档,请参阅Managing External Tables

3

什么是最佳实践取决于您确定“最佳”的标准。在许多地方,许多地方采用的方法是使用ETL工具,可能是Oracle Warehouse Builder,也许是第三方产品。这不一定是一个昂贵的产品:Pentaho免费提供水壶"self-supported" community edition

当谈到自己的时候,我认为Hibernate并不是一条可行的路。特别是如果你的主要担忧是表现。我也认为改变你的提要来生成SQL语句是一个过于复杂的解决方案。 PL/SQL模块读取文件并本机执行SQL有什么问题?

当然,当我在PL/SQL之前完成这样的事情之前,诀窍是将输入读取层与数据写入层分开。这是因为这些文件可能需要大量的定制编码,而编写的东西通常是相当通用的(这显然取决于应用程序的确切细节)。

动态元数据驱动架构是一个有吸引力的概念,特别是如果您的输入结构受到很多变化的影响。然而,这种方法很难调试和调整。代码生成是一种替代技术。

说到性能看来尽可能使用批量处理。这是PL/SQL优先于使用单个SQL语句的文件的主要原因。 Find out more

3

你想要的最后一件事是一堆插入语句...超慢的方法(不管你运行多少个进程,相信我)。将所有文件转换为分隔格式并通过sqlldr进行到Oracle的DIRECT加载将是最简单的方法(并且速度非常快)。

0

正如其他人所说,如果性能是您唯一关心的问题,您应该考虑一些工具。

但使用普通SQL语句有一些优点。许多组织都有法规,政策和顽固的开发人员来阻止任何新工具。一个简单的SQL脚本是数据库的通用语言,它几乎可以确保在任何地方工作。

如果你决定去与你需要避免脚本这样的SQL语句:

insert into my_table values(...); 
insert into my_table values(...); 
... 

并更换一条语句,工会多行:

insert into my_table 
select ... from dual union all 
select ... from dual union all 
... 

第二个版本将运行快几倍。

然而,挑选合适的尺寸是棘手的。大量小插件会浪费大量时间在通信和其他开销上。但是,Oracle解析时间以非常大的规模呈指数级增长。根据我的经验,100通常是一个很好的数字。解析变得非常慢,大约有一千个。另外,使用“union all”方法,避免多表插入技巧。由于某些原因,多表插入要慢得多,而且有些Oracle版本有错误会导致查询挂在501个表上。 (你也可以用PL/SQL创建一个有点类似的脚本,一个1兆字节的PL/SQL过程编译要比1兆字节的SQL语句解析要快得多,但是创建脚本很复杂;集合,动态sql,正确处理所有类型,创建一个临时对象,而不是一个匿名块,因为大的匿名块会导致戴安娜节点错误等。我已经构建了一个像这样的过程,它运行良好,但它可能不值得。 )