Sal*_*007 30 .net sql oracle bulkinsert
使用.NET对Oracle进行批量插入的最快方法是什么?我需要使用.NET将大约160K记录传输到Oracle.目前,我正在使用insert语句并执行160K次.完成大约需要25分钟.源数据存储在DataTable中,作为从另一个数据库(MySQL)查询的结果,
有没有更好的方法来做到这一点?
编辑:我目前正在使用System.Data.OracleClient,但愿意接受使用其他提供商(ODP.NET,DevArt等)的解决方案.
Dam*_*ian 28
我在ODP.NET中使用Array Binding在15秒左右的时间内加载了50,000条记录
它通过重复调用您指定的存储过程(并且您可以在其中执行更新/插入/删除)来工作,但它会将多个参数值从.NET传递到数据库.
您可以为每个参数指定一个值数组,而不是为存储过程的每个参数指定单个值.
Oracle一次性将参数数组从.NET传递到数据库,然后使用您指定的参数值重复调用您指定的存储过程.
http://www.oracle.com/technetwork/issue-archive/2009/09-sep/o59odpnet-085168.html
/达米安
小智 25
我最近发现了一个专门用于批量插入(ODP.NET)的类.Oracle.DataAccess.Client.OracleBulkCopy!它需要一个数据表作为参数,然后你调用WriteTOServer方法......它非常快速有效,祝你好运!
小智 16
Rob Stevenson-Legget的解决方案很慢,因为他没有绑定他的值,但他使用了string.Format().
当您要求Oracle执行sql语句时,它首先计算此语句的has值.之后,它会在哈希表中查看它是否已经知道此语句.如果它已经知道它的语句,它可以从这个哈希表中检索它的执行路径,并且非常快地执行这个语句,因为Oracle之前已经执行过这个语句.这称为库缓存,如果不绑定sql语句,它将无法正常工作.
例如,不要这样做:
int n;
for (n = 0; n < 100000; n ++)
{
mycommand.CommandText = String.Format("INSERT INTO [MyTable] ([MyId]) VALUES({0})", n + 1);
mycommand.ExecuteNonQuery();
}
Run Code Online (Sandbox Code Playgroud)
但是:
OracleParameter myparam = new OracleParameter();
int n;
mycommand.CommandText = "INSERT INTO [MyTable] ([MyId]) VALUES(?)";
mycommand.Parameters.Add(myparam);
for (n = 0; n < 100000; n ++)
{
myparam.Value = n + 1;
mycommand.ExecuteNonQuery();
}
Run Code Online (Sandbox Code Playgroud)
不使用参数也可以导致sql注入.
SQL Server的SQLBulkCopy速度非常快.不幸的是,我发现OracleBulkCopy要慢得多.还有问题:
实际上,如果要填充具有小记录但很多行的表,则System.Data.OracleClient.OracleDataAdapter比OracleBulkCopy更快.您需要调整批处理大小,OracleDataAdapter的最佳BatchSize小于OracleBulkCopy.
我在带有x86可执行文件和32位ODP.Net客户端2.112.1.0的Windows 7计算机上运行测试..OracleDataAdapter是System.Data.OracleClient 2.0.0.0的一部分.我的测试集大约是600,000行,记录大小是max.102个字节(平均大小43个字符).数据源是一个25 MB的文本文件,逐行读取为流.
在我的测试中,我将输入数据表构建为固定的表大小,然后使用OracleBulkCopy或OracleDataAdapter将数据块复制到服务器.我在OracleBulkCopy中将BatchSize保留为0(以便将当前表内容复制为一个批处理)并将其设置为OracleDataAdapter中的表大小(同样应在内部创建单个批处理).最佳成绩:
为了比较:
相同的客户端机器,测试服务器是SQL Server 2008 R2.对于SQL Server,批量复制显然是最好的方法.它不仅总体上最快,而且服务器负载也低于使用数据适配器时的服务器负载.遗憾的是,OracleBulkCopy没有提供相同的体验 - BulkCopy API比DataAdapter更容易使用.
小智 5
解决此问题的一个非常快速的方法是建立从 Oracle 数据库到 MySQL 数据库的数据库链接。您可以创建到非 Oracle 数据库的数据库链接。创建数据库链接后,您可以使用 ... create table mydata as select * from ... 语句从 MySQL 数据库检索数据。这称为异构连接。这样,您无需在 .net 应用程序中执行任何操作即可移动数据。
另一种方法是使用 ODP.NET。在 ODP.NET 中,您可以使用 OracleBulkCopy 类。
但我不认为使用 System.Data.OracleClient 在 Oracle 表中插入 160k 条记录应该花费 25 分钟。我认为你承诺的次数太多了。您是否将您的值绑定到带参数的插入语句,或者连接您的值。绑定速度要快得多。
归档时间: |
|
查看次数: |
98324 次 |
最近记录: |