极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒

C#处理大批量数据 using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleApi { /// <summary> /// 多线程批量数据处理 /// </summary> p. 阅读详情

极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒

    .Net程序中可以通过ODP调用特性,对Oracle数据库进行操作,今天来讲一下数据批量插入的功能,所用技术不高不深,相信很多朋友都接触过,小弟班门弄斧了,呵呵。这篇文章是上篇文章的续集,因为上一次试验的征集结果没有突破4秒的方法,所以这次继续挑战与挖掘新方法,虽然是Oracle,但仍具有一定收藏意义。

    上一次文章中提及的试验:

    极限挑战—C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码)

    http://www.cnblogs.com/isline/archive/2010/03/18/1688783.html

    这个试验是针对SQL SERVER数据库的,宿主环境也是.Net,有兴趣的朋友可以将这两个试验对比一下,为日后工作批量导数提供支持。

    另外,一些朋友对上次试验环境有些异议,认为应该对数据库和服务器做优化或设置,以体现试验最终的时间结果。这个固然会影响试验的时间结果,但考虑到在试验环境中,对数据库优化的标准与优化程度不便统一与定量,试验结果也不易说明其影响源,所以这次试验依然以标准数据库建库后的配置为主,试验所在服务器硬件环境与上次试验保持一致。实验目的在于挖掘、对比宿主程序中的数据批量操作方法。

    有新方法提升性能时间指标的朋友,欢迎互相切磋,互相提高,嘴上功夫就免了。。。

    好了正文开始。

    ● 普通肉垫式

    什么叫批量插入呢,就是一次性插入一批数据,我们可以把这批数据理解为一个大的数组,而这些全部只通过一个SQL来实现,而在传统方式下,需要调用很多次的SQL才可以完成,这就是著名的“数组绑定”的功能。我们先来看一下传统方式下,插入多行记录的操作方式:

 

复制代码
代码
    
// 设置一个数据库的连接串, string connectStr = " User Id=scott;Password=tiger;Data Source= " ; OracleConnection conn = new OracleConnection(connectStr); OracleCommand command = new OracleCommand(); command.Connection = conn; conn.Open(); Stopwatch sw = new Stopwatch(); sw.Start(); // 通过循环写入大量的数据,这种方法显然是肉垫 for ( int i = 0 ; i < recc; i ++ ) { string sql = " insert into dept values( " + i.ToString() + " , " + i.ToString() + " , " + i.ToString() + " ) " ; command.CommandText = sql; command.ExecuteNonQuery(); } sw.Stop(); System.Diagnostics.Debug.WriteLine( " 普通插入: " + recc.ToString() + " 所占时间: " + sw.ElapsedMilliseconds.ToString());
复制代码

 

 

    我们先准备好程序,但是先不做时间的测定,因为在后面我们会用多次循环的方式来计算所占用的时间。

    ● 使用ODP特性

    看上面的程序,大家都很熟悉,因为它没有用到任何ODP的特性,而紧接着我们就要来介绍一个神奇的程序了,我们看一下代码,为了更直观,我把所有的注释及说明直接写在代码里:

 

代码
复制代码
    
// 设置一个数据库的连接串 string connectStr = " User Id=scott;Password=tiger;Data Source= " ; OracleConnection conn = new OracleConnection(connectStr); OracleCommand command = new OracleCommand(); command.Connection = conn; // 到此为止,还都是我们熟悉的代码,下面就要开始喽 // 这个参数需要指定每次批插入的记录数 command.ArrayBindCount = recc; // 在这个命令行中,用到了参数,参数我们很熟悉,但是这个参数在传值的时候 // 用到的是数组,而不是单个的值,这就是它独特的地方 command.CommandText = " insert into dept values(:deptno, :deptname, :loc) " ; conn.Open(); // 下面定义几个数组,分别表示三个字段,数组的长度由参数直接给出 int [] deptNo = new int [recc]; string [] dname = new string [recc]; string [] loc = new string [recc]; // 为了传递参数,不可避免的要使用参数,下面会连续定义三个 // 从名称可以直接看出每个参数的含义,不在每个解释了 OracleParameter deptNoParam = new OracleParameter( " deptno " , OracleDbType.Int32); deptNoParam.Direction = ParameterDirection.Input; deptNoParam.Value = deptNo; command.Parameters.Add(deptNoParam); OracleParameter deptNameParam = new OracleParameter( " deptname " , OracleDbType.Varchar2); deptNameParam.Direction = ParameterDirection.Input; deptNameParam.Value = dname; command.Parameters.Add(deptNameParam); OracleParameter deptLocParam = new OracleParameter( " loc " , OracleDbType.Varchar2); deptLocParam.Direction = ParameterDirection.Input; deptLocParam.Value = loc; command.Parameters.Add(deptLocParam); Stopwatch sw = new Stopwatch(); sw.Start(); // 在下面的循环中,先把数组定义好,而不是像上面那样直接生成SQL for ( int i = 0 ; i < recc; i ++ ) { deptNo[i] = i; dname[i] = i.ToString(); loc[i] = i.ToString(); } // 这个调用将把参数数组传进SQL,同时写入数据库 command.ExecuteNonQuery(); sw.Stop(); System.Diagnostics.Debug.WriteLine( " 批量插入: " + recc.ToString() + " 所占时间: " + sw.ElapsedMilliseconds.ToString());
复制代码

 

 

    以上代码略显冗长,但是加上注释后基本也就表达清楚了。

    好了,到目前为止,两种方式的插入操作程序已经完成,就剩下对比了。我在主函数处写了一个小函数,循环多次对两个方法进行调用,并且同时记录下时间,对比函数如下:

 

复制代码
   
for ( int i = 1 ; i <= 50 ; i ++ ) { Truncate(); OrdinaryInsert(i * 1000 ); Truncate(); BatchInsert(i * 1000 ); }
复制代码

 

 

    当数据量达到100万级别时,所用时间依然令人满意,最快一次达到890毫秒,一般为1秒左右。

    经过试验,得出一组数据,可以看出两种方式在效率方面惊人的差距(占用时间的单位为毫秒),部分数据如下:

记录数

标准

批处理

1000

1545

29

2000

3514

20

3000

3749

113

4000

5737

40

5000

6820

52

6000

9469

72

7000

10226

69

8000

15280

123

9000

11475

83

10000

14536

121

11000

15705

130

12000

16548

145

13000

18765

125

14000

20393

116

15000

22181

159

 
因为篇幅原因,不再粘贴全部的数据,但是我们可以看一下由此数据生成的散点图:

clip_image002

 

    其中有些数据有些跳跃,可能和数据库本身有关系,但是大部分数据已经能说明问题了。看了这些数据后,是不是有些心动了?

    源程序放了一段时间直接拷贝贴过来了,可能需要调试一下才能跑通,不过不是本质性问题,对了如果要测试别忘记安装Oracle访问组件。

极限挑战—C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码) 极限挑战—C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码) 以上就是这几天的实验结果了,比较令人失望的是SQL SERVER 2008导入数据的性能似乎并不想我们想象的那样优秀。 另外,有下载源代码的帮我看看,为什么多线程的成绩还不如单线程的优秀呢?是静态资源使用不当造成的,还是其他什么原因? 立即下载

相关推荐

C#编写实现定时备份ORACLE数据库的辅助小程序

这是一个由C#编写,用于实现定时备份ORACLE数据库的辅助小程序。程序运行后会在程序所在目录生成一个exp_run.par文件和Export.bat文件,然后执行Export.bat文件来进行备份ORACLE数据库。但程序本身并为实现定时的功能,所以我们要配合window系统自带的计划任务 ,来让这个程序实现定时执行的效果。

C#存数据遍历比较100万条

List的遍历效率时间 /// <summary> /// List的性能 /// </summary> public void ListShiy() { Stopwatch sw = new Stopwatch(); sw.Start(); ...

qq_44060573的博客 3639

Oracle小程序(连接Oracle服务器)

不需要安装Oracle客户端就可以访问服务器。

如何快速向数据库插1000万数据?4种方法对比,它简单却速度最快

前言 一直有一种说法:批量插入大量数据到MySQL数据库,不要使用Mybatis、Hibernate之类的ORM框架,原因一般都是说性能不好,至于为什么不好好像没几个人能讲清楚的。 批量插入大量数据最优的方式是什么?网上也是众说纷纭。不如自己动手测试一下吧! 场景介绍 前几天公司项目进行压力测试,测试某个功能在大数据量(千万级)的情况下是否能够正常运行,可是项目还没有正式上线运营,数据库里...

勇往直前的专栏 2万+

我用两个月时间,终于把优快云付费资源项目玩明白了!

关于项目的定位,这是一个知识付费项目,根据市场研究机构的数据显示,到2023年,全球知识付费市场规模将达到2000亿美元,所以说知识付费的前景是十分广阔的,当下互联网时代信息大爆炸,80后、90后、00后群体对知识付费的认可度也大幅提升,同时这群作为知识付费的主流人群已经具备了更强的消费能力,而且对于知识付费的需求更高。目前整个知识付费领域仍然在发展起步的初期,尽快在知识付费领域布局可以帮助我们在这波红利中获得一份不错的收益。而且个人认为,

白话机器学习 2万+

从零开始:TexLive(Latex)安装与配置全指南

本文提供了一份详尽的TexLive(Latex)安装与配置全指南,旨在帮助用户从零开始快速搭建LaTeX工作环境。内容涵盖从镜像下载、安装步骤详解、环境验证到高效编辑器(如VS Code)配置,并特别强调了中文排版支持与宏包管理,确保用户能顺利处理学术论文等专业文档的排版需求。

weixin_29284885的博客 903

oracle odp arraybindcount 极限,極限挑戰—C#+ODP 100萬條數據導入Oracle數據庫僅用不到1秒...

.Net程序中可以通過ODP調用特性,對Oracle數據庫進行操作,今天來講一下數據批量插入的功能,所用技術不高不深,相信很多朋友都接觸過,小弟班門弄斧了,呵呵。這篇文章是上篇文章的續集,因為上一次試驗的征集結果沒有突破4秒的方法,所以這次繼續挑戰與挖掘新方法,雖然是Oracle,但仍具有一定收藏意義。上一次文章中提及的試驗:這個試驗是針對SQL SERVER數據庫的,宿主環境也是.Net,有興趣...

weixin_33459498的博客 412

别再到处找包了!Keil5芯片支持包(Pack)最全管理指南:安装、更新、迁移与离线备份

本文详细解析了Keil5芯片支持包(Pack)的全生命周期管理,包括安装、更新、迁移与离线备份的工程化解决方案。针对STM32F10x等常见芯片,提供了高效获取Pack的策略、版本管理技巧及团队协作方案,帮助开发者解决常见的'Device Family Pack missing'等问题,提升嵌入式开发效率。

weixin_28729205的博客 541

oracle百万数据导入mysql_极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒...

.Net程序中可以通过ODP调用特性,对Oracle数据库进行操作,今天来讲一下数据批量插入的功能,所用技术不高不深,相信很多朋友都接触过,小弟班门弄斧了,呵呵。这篇文章是上篇文章的续集,因为上一次试验的征集结果没有突破4秒的方法,所以这次继续挑战与挖掘新方法,虽然是Oracle,但仍具有一定收藏意义。上一次文章中提及的试验:这个试验是针对SQL SERVER数据库的,宿主环境也是.Net,有兴趣...

weixin_36296064的博客 391

告别DLTS的模糊地带:手把手教你用拉普拉斯深能级瞬态光谱(LDLTS)精准揪出半导体缺陷

本文详细介绍了拉普拉斯深能级瞬态光谱(LDLTS)技术在半导体缺陷检测中的高分辨率解决方案。相比传统DLTS,LDLTS通过拉普拉斯变换和正则化算法,将分辨率提升至1meV,有效解析复杂重叠缺陷谱,适用于硅、GaN等材料的精确缺陷分析。文章涵盖LDLTS原理、系统搭建、测量流程及工业应用案例,为半导体工艺优化提供强大工具。

weixin_29238147的博客 193

运用AD进行stm32最小系统PCB图的绘制

运用AD进行stm32最小系统PCB图的绘制一、PCB图的绘制(1)布局(2)布线(3)覆铜(4)电气规则检查二、给PCB添加logo三、生成garber文件总结 一、PCB图的绘制 (1)布局 1.画好原理图后,新建一个PCB项目 2.在Design中选择第二项,导入器件 3.先点击右下角第一项,再点第二项导入器件 导入成功 4.导入后效果 选择紫红色方框,按电脑上的delete键把它删掉 5.在Tools选择Outside Board,自动排布器件 排布后效果如图 6.画线,确定板子范围

lucario1的博客 2149

C#中利用ODP实现瞬间导入百万级数据详解

.NET程序中可以通过ODP调用特性,对Oracle数据库进行操作,今天来讲一下数据批量插入的功能,所用技术不高不深,相信很多朋友都接触过,小弟班门弄斧了,呵呵。这篇文章是上篇文章的续集,因为上一次试验的征集结果没有突破4秒的方法,所以这次继续挑战与挖掘新方法,虽然是Oracle,但仍具有一定收藏意义。 上一次文章中提及的试验: 极限挑战—C#100万条数据导入SQL SERVER数据库仅用4

未来软件 1051

[语义分割]SPP、空洞卷积与ASPP总结

ASPP全称:Atrous Spatial Pyramid Pooling,中文可以理解为空洞空间卷积池化金字塔或者多孔空间金字塔池化。在这其中,要理解两个概念:一个是SPP,池化金字塔结构或者叫空间金字塔池化层,都是一个东西;另一个是Atrous,空洞卷积,两个加在一起就是ASPP。 首先说一下SPP:Spatial Pyramid Pooling。这个结构出自于论文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Re

lipengfei0427的博客 2万+
上一篇: WPF自定义控件快速构成窗体布局
下一篇: oracle ODP.NET 批量插入或更新
fighter_yy
博客等级 码龄20年 22粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值