Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1634398
  • 博文数量: 201
  • 博客积分: 2812
  • 博客等级: 少校
  • 技术积分: 3029
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-18 18:28
个人简介

从事数据库工作多年,目前看好分布式NeSQL/HTAP数据库在企业客户市场的发展。未来的主要方向是——致力于 NewSQL/HTAP 数据库的推广普及。

文章存档

2016年(1)

2015年(8)

2014年(23)

2013年(50)

2012年(32)

2011年(87)

分类: Sybase

2011-07-21 09:56:16

   对于Sybase IQ来说,往表中“插入/装入”数据从功能上说可以有如下方法:
   (1) 使用LOAD TABLE语句把文本文件中的数据装载到IQ的表中
   (2) 使用INSERT INTO SELECT/SELECT INTO FROM/INSERT LOATION把一个表中的记录写入另一个表中
   (3) INSERT INTO VALUES又叫做单条INSERT/即一次插入一条记录
   (4) 使用Sybase Open Client提供的bcp in
 
   这几种方法功能上类似,但是在性能上的表现却有很大不同(特别是在插入数据量比较大时)。一般来说,性能表现是按照上面所给出方法的序号顺序依次变慢。即(1)是最快的方法,(4)是最慢的方法。特别是(4)最好不使用,当记录数大于几千时应严禁使用这种方法。
 
   在这篇博文中我举一个方法(3)的例子,这个例子来自于我支持的一个项目。该项目有一个存储过程,在测试时发现执行的速度比较慢,特别是在多并发情况下就更严重。出于保密的考虑,这里只给出优化前该存储过程的部分经修改的片段:
   --原存储过程代码片段
   ......
   set rseString=startValue;
   while(rseString <= endValue) loop
     set sqlstr='insert into #temp11 values(''' || rseString || ''')';
     execute immediate sqlstr;
     call proc_other(rseString,param2,param3,...);
     if rseString is null then
        return 0
      end if
   end loop
   ......
 
   大家注意上面代码片段中的那两行蓝色的代码,该代码使用了insert into values方法,即单条insert方法。这种方法在Sybase IQ中执行,大概的速度是2~100行/秒。如果该循环次数较多,比如几百、几千次甚至更多,那么执行速度就会比较慢。找到原因了,那么如何优化它呢?如果把单条insert改为“成批”insert,即方法(2)的INSERT SELECT方法就可以解决问题了。下面是优化后的存储过程代码:
   ......
   set rseString=startValue;
   set sqlstr=' insert into #temp11 ';
   set i = 1;
   while(rseString <= endValue) loop
     if (i = 1) then
       set sqlstr= sqlstr || ' select ' || rseString || ' ' ;
     else
       set sqlstr= sqlstr || ' union all select  ' || rseString ;
     end if ;
     call proc_other(rseString,param2,param3,...);
     if rseString is null then
        execute immediate sqlstr;
        return 0
     end if
     set i = i+1;
   end loop
   execute immediate sqlstr;
   ......
 
   上面的代码可能有点复杂,我举一个简化的例子以说明问题:
   --假设往test11表中写入四条记录,采用单条insert方法
   insert into test11 value(‘aaaaa’);
   insert into test11 value(‘bbbbb’);
   insert into test11 value(‘ccccc’);
   insert into test11 value(‘ddddd’);
 
   --我们知道这种方法的效率不高,改为批量insert会提升性能
    insert into test11
    select 'aaaaa'
    union all
    select 'bbbbb'
    union all
    select 'ccccc'
    union all
    select 'ddddd';
   
    如果大家理解了上面的这个简单例子的原理,那么对于那个用户存储过程修改的代码就好理解了。
 
 
阅读(8186) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~