免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 8858 | 回复: 5

ORACLE OCI 批量插入试验 [复制链接]

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
发表于 2010-04-02 16:45 |显示全部楼层
本帖最后由 yulihua49 于 2010-04-02 16:48 编辑

测试一下批量插入,在这个表存储过程单条插入100000条大约是3.6秒。
OCI批量插入100000条,
每批10条:1.2秒
100条:0.45秒。
1000条:0.27秒
单条:8.7秒。
批量还是有巨大优势,但不好管理。
下例在DAU环境下自己调sqlora完成:可以看到不用包装器,程序还是挺繁的,尤其是当列比较多时,而且还不通用。

  1. tuxticket@jgbticket:~/test> cat ti.c
  2. /*************************************

  3. create table T (
  4.         I1 number(6),
  5.         I2 number(6),
  6.         I3 number(6),
  7.         I4 number(6)
  8. );

  9. PK:
  10. create or replace procedure ti
  11. IS
  12. I   integer;
  13. BEGIN
  14.      FOR I IN 1..100000 LOOP
  15.       INSERT INTO T VALUES (I,I,I,I);
  16.      END LOOP;
  17. END;
  18. /
  19. 测试批量插入
  20. ***************************************/

  21. #include <DAU.h>

  22. #define BATCH 1000

  23. typedef struct {
  24.         int i1;
  25.         int i2;
  26.         int i3;
  27.         int i4;
  28.         short i1_ind;
  29.         short i2_ind;
  30.         short i3_ind;
  31.         short i4_ind;
  32. } ti_stu;

  33. main(int argc,char *argv[])
  34. {
  35. int i,j,num=0;
  36. int ret;
  37. T_SQL_Connect SQL_Connect;
  38. INT64 now;
  39. sqlo_stmt_handle_t cursor;
  40. char *result=0,stmt[1024];
  41. ti_stu ti[BATCH];

  42.         if(argc>1) ret=envcfg(argv[1]);

  43.         ret=db_open(&SQL_Connect);
  44.         if(ret) {
  45.                 printf("OPEN_Database %s,err=%d.%s\n",
  46.                         SQL_Connect.DBOWN,
  47.                         SQL_Connect.Errno,
  48.                         SQL_Connect.ErrMsg);
  49.                 return 1;
  50.         }

  51.         for(i=0;i<BATCH;i++)
  52.                 ti[i].i1_ind=ti[i].i2_ind=ti[i].i3_ind=ti[i].i4_ind=0;
  53.         sprintf(stmt,"INSERT INTO %s.T (I1,I2,I3,I4) VALUES(:1,:2,:3,:4)",SQL_Connect.DBOWN);
  54.         cursor=sqlo_prepare(SQL_Connect.dbh,stmt);
  55.         if(cursor < 0) {
  56.                 ___SQL_GetError(&SQL_Connect);
  57.                 printf("sqlo_prepare err=%d,%s\n",
  58.                         SQL_Connect.Errno,
  59.                         SQL_Connect.ErrMsg);
  60.                 ___SQL_CloseDatabase__(&SQL_Connect);
  61.                 return 2;
  62.         }
  63. printf("stmt=%s\n",stmt);
  64.         if((0>sqlo_bind_by_pos2(cursor,1,SQLOT_INT,&ti[0].i1,sizeof(int),&ti[0].i1_ind,0,sizeof(ti_stu))) ||
  65.            (0>sqlo_bind_by_pos2(cursor,2,SQLOT_INT,&ti[0].i2,sizeof(int),&ti[0].i2_ind,0,sizeof(ti_stu))) ||
  66.            (0>sqlo_bind_by_pos2(cursor,3,SQLOT_INT,&ti[0].i3,sizeof(int),&ti[0].i3_ind,0,sizeof(ti_stu))) ||
  67.            (0>sqlo_bind_by_pos2(cursor,4,SQLOT_INT,&ti[0].i4,sizeof(int),&ti[0].i4_ind,0,sizeof(ti_stu)))) {
  68.                 ___SQL_GetError(&SQL_Connect);
  69.                 printf("sqlo_bind err=%d,%s\n",
  70.                         SQL_Connect.Errno,
  71.                         SQL_Connect.ErrMsg);
  72.                 ___SQL_Close__(&SQL_Connect,cursor);
  73.                 ___SQL_CloseDatabase__(&SQL_Connect);
  74.                 return 3;
  75.         }

  76.         j=0;
  77.         now=now_usec();
  78.         for(i=0;i<100000;i++) {
  79.                 ti[j].i1=ti[j].i2=ti[j].i3=ti[j].i4=i;
  80.                 if(BATCH==++j) {
  81.                         ret=sqlo_execute(cursor,j);
  82.                                 j=0;
  83.                         if(ret) {
  84.                                 ___SQL_GetError(&SQL_Connect);
  85.                                 printf("sqlo_execute err=%d,%s\n",
  86.                                         SQL_Connect.Errno,
  87.                                         SQL_Connect.ErrMsg);
  88.                                 break;
  89.                         }
  90.                         num+=sqlo_prows(cursor);
  91.                 }
  92.         }
  93.         printf("insert %dRec's num=%d,TIMEVAL=%lldus\n",i,num,now_usec()-now);

  94.         strcpy(stmt,"TICKET.TI");
  95.         now=now_usec();
  96.         ret=ORA_Rpc(&SQL_Connect,stmt,&result);
  97.         printf("ORA_Rpc:return=%d,TIMEVAL=%lldus\n",ret,now_usec()-now);

  98.         ___SQL_Transaction__(&SQL_Connect,TRANROLLBACK);
  99.         ___SQL_CloseDatabase__(&SQL_Connect);
  100. }
  101. tuxticket@jgbticket:~/test> ./ti ld.ini
  102. stmt=INSERT INTO TICKET.T (I1,I2,I3,I4) VALUES(:1,:2,:3,:4)
  103. insert 100000Rec's num=100000,TIMEVAL=269855us
  104. ORA_Rpc:return=0,TIMEVAL=3628331us
  105. [ 本帖最后由 yulihua49 于 2010-4-2 15:12 编辑 ]
复制代码
__________________
欢迎到我的blog:
http://blog.chinaunix.net/u3/92831/

论坛徽章:
0
发表于 2011-03-02 15:22 |显示全部楼层

论坛徽章:
1
辰龙
日期:2013-11-20 14:55:50
发表于 2011-03-15 10:31 |显示全部楼层

论坛徽章:
59
2015七夕节徽章
日期:2015-08-24 11:17:25ChinaUnix专家徽章
日期:2015-07-20 09:19:30每周论坛发贴之星
日期:2015-07-20 09:19:42ChinaUnix元老
日期:2015-07-20 11:04:38荣誉版主
日期:2015-07-20 11:05:19巳蛇
日期:2015-07-20 11:05:26CU十二周年纪念徽章
日期:2015-07-20 11:05:27IT运维版块每日发帖之星
日期:2015-07-20 11:05:34操作系统版块每日发帖之星
日期:2015-07-20 11:05:36程序设计版块每日发帖之星
日期:2015-07-20 11:05:40数据库技术版块每日发帖之星
日期:2015-07-20 11:05:432015年辞旧岁徽章
日期:2015-07-20 11:05:44
发表于 2011-03-15 21:33 |显示全部楼层
没写过OCI程序。楼主太牛。

论坛徽章:
0
发表于 2012-08-11 20:43 |显示全部楼层
@yulihua49请教楼主一个问题
请问下面几种数据插入的方式的性能有没有什么本质上的区别?
1. 使用sqlldr的非direct方式
2. oci接口的batch insert方式
3. for循环一条一条的插入
个人觉得sqlldr非direct方式应该和oci的batch insert性能差不多。for循环的话,其实我也觉得差不多,除了batch insert是一次通信就把数据发给了数据库,而for循环需要跟数据库通信好多次。但是看你的测试数据好像batch insert性能好不少啊,会是什么原因导致性能提升的呢?

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
发表于 2014-03-25 16:12 |显示全部楼层
本帖最后由 yulihua49 于 2014-03-25 16:14 编辑
willus 发表于 2012-08-11 20:43
@yulihua49请教楼主一个问题
请问下面几种数据插入的方式的性能有没有什么本质上的区别?
1. 使用sqlldr的 ...

http://www.itpub.net/thread-1738533-8-1.html
79楼。
用3个线程,一个负责读文件,两个负责写数据库。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP