0 0

ibatis 我用insert ....select...语句执行insert动作,但是执行速度很慢10

如题
我在ibatis里面编写inserts tatment
实现insert.....select....这样的insert功能,但是发现ibatis的运行速度非常慢,同样的sql在jdbc方式下却非常快,坛子里的达人有没有什么方法能够提升在ibatis里面的insert速度,如果没有办法我只有放弃ibatis了。
大家讨论一下。
问题补充:
我的sql具体如下:
其实就是从别的库里面select后把统计结果insert 到另外的表中
insert into ACCO_STATISTICAL_DAILY 
select 1 opid,spid,1 prodclasssn,3 servtypesn,to_date(#beginDate#,'yyyy-mm-dd') sumdate, areaid,provinceid,prodsn,0 price,nvl(feecodeid,-1),chan72,0 usernum,
       sum(callnum) callnum,0 timeunit,0 totalamt,0 totalearn,0 baseusernum,sum(basecallnum) basecallnum,0 basetotalamt,0 basetotalearn, nvl(ptnsn,-1),''causedeptid,'02' loadtype
   from( select chan72,nvl(provinceid,-1) provinceid,nvl(a.areaid,-1) areaid,productid prodsn,validdate,spid,a.feecodeid,sum(callnum) callnum,sum(basecallnum) basecallnum    
           from (select substr(channel,1,72) chan72,areaid,a.productid,to_char(validdate,'yyyy-mm-dd') validdate,A.feecodeid,sum(callnum) callnum,
                             sum(case when billdate=to_date(#firstDate#,'yyyy-mm-dd') then callnum else 0 end ) basecallnum
           from (select userid,productid,feecodeid,count(*) callnum
               from acctn.sms_deliver_month a
              where deliverdate>=to_date(#firstDate#,'yyyy-mm-dd')
                and deliverdate <to_date(#endDate#,'yyyy-mm-dd')
              group by userid,productid,feecodeid ) A,
              (select *
                   from acctn.sms_bill_baoyue 
                  where billdate>=to_date(#firstDate#,'yyyy-mm-dd')
                and billdate <to_date(#endDate#,'yyyy-mm-dd')
                and validdate>=to_date(#beginDate#,'yyyy-mm-dd')
                    and validdate <to_date(#endDate#,'yyyy-mm-dd') ) B
       where A.userid=B.userid
        and A.productid=B.productid
        and A.feecodeid=B.feecodeid
       group by substr(channel,1,72),areaid,a.productid,areaid,to_char(validdate,'yyyy-mm-dd'),A.feecodeid ) A,
acctn.area B,(select a.feecodeid,a.nodeid,b.spid,c.spname
                                 from acctn.sms_fee_code a, acctn.sms_node b,acctn.service_provider c
                                where a.nodeid=b.nodeid
                                  and b.spid=c.spid) C
where A.areaid=B.areaid(+)
   and A.feecodeid=C.feecodeid
group by chan72,nvl(provinceid,-1),nvl(a.areaid,-1),productid,validdate,spid,a.feecodeid
union all
select chan72,nvl(provinceid,-1) provinceid,nvl(a.areaid,-1) areaid,productid prodsn,validdate,spid,a.feecodeid,sum(callnum) callnum ,sum(basecallnum) basecallnum  
           from (select substr(channel,1,72) chan72,areaid,to_char(validdate,'yyyy-mm-dd') validdate,a.productid,A.feecodeid,sum(callnum) callnum ,
                                sum(case when billdate=to_date(#firstDate#,'yyyy-mm-dd') then callnum else 0 end ) basecallnum
           from (select userid,productid,feecodeid,count(*) callnum
               from acctn.sms_deliver_month a
              where deliverdate>=to_date(#beginDate#,'yyyy-mm-dd')
                and deliverdate <to_date(#endDate#,'yyyy-mm-dd')
              group by userid,productid,feecodeid ) A,
              (select *
                   from acctn.sms_bill_baoyue
                  where billdate>=to_date(#firstDate#,'yyyy-mm-dd')
                and billdate <to_date(#endDate#,'yyyy-mm-dd')
                and validdate>=to_date(#firstDate#,'yyyy-mm-dd')
                    and validdate <to_date(#beginDate#,'yyyy-mm-dd') ) B
          where A.userid=B.userid
            and A.productid=B.productid
            and A.feecodeid=B.feecodeid
          group by substr(channel,1,72),areaid,a.productid,areaid,to_char(validdate,'yyyy-mm-dd'),A.feecodeid ) A,
        acctn.area B,(select a.feecodeid,a.nodeid,b.spid,c.spname
                                                                   from acctn.sms_fee_code a, acctn.sms_node b,acctn.service_provider c
                                                                  where a.nodeid=b.nodeid
                                                                    and b.spid=c.spid) C
  where A.areaid=B.areaid(+)
    and A.feecodeid=C.feecodeid
  group by chan72,nvl(provinceid,-1),nvl(a.areaid,-1),productid,validdate,spid,a.feecodeid  ) A,
            (select *
               from getchan_prj
              where prodclasssn=1) B
    where substr(A.chan72,1,5) = B.ordprefix(+)
  group by spid,areaid,provinceid,prodsn,feecodeid,chan72,ptnsn



具体java代码如下:
SqlMapClient sqlMapperacct = null;
try {
          Reader reader = Resources.getResourceAsReader("com/airinbox/datamanager/data/SqlMapConfig.xml");
          sqlMapperacct = SqlMapClientBuilder.buildSqlMapClient(reader);
         
          reader.close();
          System.out.println("sqlMapperacct:"+sqlMapperacct);
        } catch (IOException e) {
          throw new RuntimeException("Exception!" + e, e);
        } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
    Map parameter = new HashMap();
    parameter.put("firstDate", beginDate.substring(1,7)+"-01");
    parameter.put("beginDate", beginDate);
    parameter.put("endDate", DateTime.getAddDate(beginDate,1));
logger.info("insert SMS BaoYue Date ."+beginDate+" Start time "+new Date());
sqlMapperacct.startTransaction();
//sqlMapperacct.getDataSource().getConnection().createStatement().execute("");
//sqlMapperacct.update("insertSMSBY_02",parameter);
sqlMapperacct.insert("insertSMSBY_02",parameter);
sqlMapperacct.commitTransaction();
logger.info("Over . End Time : "+new Date());
请joachimz 和fudehai001 看看,我在jdbc下执行上面sql也就不到1分钟
但是在ibatis里面要用大概20分钟。

问题补充:
*****************************************
您给的建议都是针对sql级别的优化,但是对于ibatis我依然没感觉到速度有提升。如果说这样的sql(insert....select...from...where)这样的语句对于ibatis是很高深的sql的话我觉得ibatis有点太傻了,
其实使用ibatis就是想把sql和java代码分离开,但是如果效率无法保证的话很让我失望,希望“fudehai001”同学和“joachimz”同学能给出ibatis上的间接。我一直怀疑是不是我使用ibatis的方式不对,但是问题也无法找到,郁闷中。
2008年12月05日 17:00

4个答案 按时间排序 按投票排序

0 0

呵呵,前面没有仔细看你的使用情况,问题应该出在这里:

SqlMapClient sqlMapperacct = null; 
try { 
          Reader reader = Resources.getResourceAsReader("com/airinbox/datamanager/data/SqlMapConfig.xml"); 
          sqlMapperacct = SqlMapClientBuilder.buildSqlMapClient(reader); 
          
          reader.close(); 
          System.out.println("sqlMapperacct:"+sqlMapperacct); 
        } catch (IOException e) { 
          throw new RuntimeException("Exception!" + e, e); 
        } catch (Exception e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
} 

SqlMapClient对象应该被缓存起来,全局使用,而不能每次都去新构建。

像我这里有几十个sqlmap.xml,总计有上千个statement,每次初始化创建差不多要1分钟。

2008年12月19日 23:58
0 0

1,强烈建议放到存贮过程中调用,因为这个sql稍复杂,ibatis智商不知有这么高没:(
2,查询条件中别用函数,会造成索引失效
3,count(*) 改为 count(1) ,这样更快
4,还不行看看执行计划
5, sql写规范点好看哈
insert into ACCO_STATISTICAL_DAILY
select 1 opid
       ,spid
       ,1 prodclasssn
       ,3 servtypesn
       ,to_date(#beginDate#,'yyyy-mm-dd') sumdate
       , areaid,provinceid,prodsn
       ,0 price
       ,nvl(feecodeid,-1)
       ,chan72
       ,0 usernum,
       sum(callnum) callnum
       ,0 timeunit
       ,0 totalamt
       ,0 totalearn
       ,0 baseusernum
       ,sum(basecallnum) basecallnum
       ,0 basetotalamt
       ,0 basetotalearn
       , nvl(ptnsn,-1)
       ,''causedeptid
       ,'02' loadtype
   from( select chan72
               ,nvl(provinceid,-1) provinceid
               ,nvl(a.areaid,-1) areaid
               ,productid prodsn
               ,validdate
               ,spid
               ,a.feecodeid
               ,sum(callnum) callnum
               ,sum(basecallnum) basecallnum   
           from (select substr(channel,1,72) chan72
                       ,areaid
                       ,a.productid
                       ,to_char(validdate,'yyyy-mm-dd') validdate
                       ,A.feecodeid
                       ,sum(callnum) callnum
                       ,sum(case when billdate=to_date(#firstDate#,'yyyy-mm-dd') then callnum else 0 end  )basecallnum
                  from (select userid
                               ,productid
                               ,feecodeid
                               ,count(*) callnum --改为count(1)更快
                           from acctn.sms_deliver_month a
                          where deliverdate>=to_date(#firstDate#,'yyyy-mm-dd')
                            and deliverdate <to_date(#endDate#,'yyyy-mm-dd')
                          group by userid,productid,feecodeid
                         ) A
                         ,(select *  --别用星号,表结果更改时程序会报错
                            from acctn.sms_bill_baoyue
                            where billdate>=to_date(#firstDate#,'yyyy-mm-dd')
                              and billdate <to_date(#endDate#,'yyyy-mm-dd')
                              and validdate>=to_date(#beginDate#,'yyyy-mm-dd')
                              and validdate <to_date(#endDate#,'yyyy-mm-dd')
                          ) B
                   where A.userid=B.userid
                     and A.productid=B.productid
                     and A.feecodeid=B.feecodeid
                   group by substr(channel,1,72)
                            ,areaid
                            ,a.productid
                            ,areaid
                            ,to_char(validdate,'yyyy-mm-dd')
                            ,A.feecodeid
               ) A --表别名内外相同,建议更改,应该是通不过编译吧,没具体试过
               ,acctn.area B
               ,(select a.feecodeid
                       ,a.nodeid
                       ,b.spid
                       ,c.spname
                  from acctn.sms_fee_code a
                      ,acctn.sms_node b
                      ,acctn.service_provider c
                 where a.nodeid=b.nodeid
                   and b.spid=c.spid
                  ) C
   where A.areaid=B.areaid(+)
     and A.feecodeid=C.feecodeid
  group by chan72,nvl(provinceid,-1),nvl(a.areaid,-1),productid,validdate,spid,a.feecodeid
union all
select chan72
      ,nvl(provinceid,-1) provinceid
      ,nvl(a.areaid,-1) areaid
      ,productid prodsn
      ,validdate
      ,spid
      ,a.feecodeid
      ,sum(callnum) callnum
      ,sum(basecallnum) basecallnum 
from (select substr(channel,1,72) chan72
            ,areaid
            ,to_char(validdate,'yyyy-mm-dd') validdate
            ,a.productid
            ,A.feecodeid
            ,sum(callnum) callnum
            , sum(case when billdate=to_date(#firstDate#,'yyyy-mm-dd') then callnum else 0 end ) basecallnum
        from (select userid
                    ,productid
                    ,feecodeid
                    ,count(*) callnum --改为count(1)更快
               from acctn.sms_deliver_month a
              where deliverdate>=to_date(#beginDate#,'yyyy-mm-dd')
                and deliverdate <to_date(#endDate#,'yyyy-mm-dd')
              group by userid,productid,feecodeid
              ) A,
             (select *
               from acctn.sms_bill_baoyue
              where billdate>= to_date(#firstDate#,'yyyy-mm-dd')
                and billdate < to_date(#endDate#,'yyyy-mm-dd')
                and validdate >= to_date(#firstDate#,'yyyy-mm-dd')
                and validdate < to_date(#beginDate#,'yyyy-mm-dd')
              ) B
        where A.userid=B.userid
          and A.productid=B.productid
          and A.feecodeid=B.feecodeid
        group by substr(channel,1,72),areaid,a.productid,areaid,to_char(validdate,'yyyy-mm-dd'),A.feecodeid
       ) A
       ,acctn.area B
       ,(select a.feecodeid
                ,a.nodeid
                ,b.spid
                ,c.spname
           from acctn.sms_fee_code a
               ,acctn.sms_node b
               ,acctn.service_provider c
          where a.nodeid=b.nodeid
            and b.spid=c.spid
         ) C
   where A.areaid=B.areaid(+)
     and A.feecodeid=C.feecodeid
   group by chan72,nvl(provinceid,-1),nvl(a.areaid,-1),productid,validdate,spid,a.feecodeid 
    ) A,
    (select * --别用星号,表结果更改时程序会报错
       from getchan_prj
      where prodclasssn=1
    ) B
where substr(A.chan72,1,5) = B.ordprefix(+) --条件上用函数会使索引失效(这个因素可能性最大)
group by spid,areaid,provinceid,prodsn,feecodeid,chan72,ptnsn

2008年12月14日 18:22
0 0

应该不是ibatis问题,
把具体sql发出来看看哈。
看看相关表上的索引哈,是否最近有对表进行DDL变更。

2008年12月06日 20:26
0 0

实际上Ibatis就是在使用jdbc,我这里应用非常多,都是大数据量的处理,都没有问题。

类似问题我也遇到过,最后检查发现是sql的执行计划不同导致,因此建议你先找出慢在什么地方,再来分析原因。

2008年12月05日 23:49

相关推荐

    ibatis-sqlmap-2.3.4.726-sources.jar.zip_birth84v_cutting1v2_ibat

    在2.3.4.726这个版本中,我们可以期待看到一些关键组件,如SqlMapConfig.xml配置文件的解析逻辑,SqlMapClient的构建和执行SQL的方法,以及Statement类型的定义(例如,SelectStatement、InsertStatement等)。...

    ibatis2.3.4.726增删改查源码实例

    在本实例中,"ibatis2.3.4.726增删改查源码实例" 提供了一个完整的基于Ibatis 2.3.4.726版本的开发案例,涵盖了数据库的基本操作,即增(INSERT)、删(DELETE)、改(UPDATE)和查(SELECT)。 首先,我们来了解...

    Manning.iBATIS.in.Action.Jan.2007.eBook-BBL.pdf

    - **映射语句**:iBATIS使用XML映射文件来定义数据库操作,这些映射文件包含了SQL语句以及它们与Java对象之间的映射关系。每个映射文件都包含了一系列的`&lt;select&gt;`、`&lt;insert&gt;`、`&lt;update&gt;`和`&lt;delete&gt;`元素,每个...

    iBatis文档\ibatis.doc

    `XmlSqlMapClientBuilder`用于构建SqlMapClient实例,它是iBatis的核心接口,提供了执行SQL语句和处理结果集的方法。例如,你可以这样创建SqlMapClient: ```java SqlMapClient sqlMap = SqlMapClientBuilder....

    ibatis-core-3.0.jar.zip

    3. SqlSession:SqlSession接口是实际执行SQL的地方,提供了一系列的方法,如selectOne、selectList、insert、update和delete,用于执行SQL语句。 4. MapperRegistry:负责注册Mapper接口,使得可以通过Mapper接口...

    10_ibatis教程_ibatis-2.3.3.720.zip

    在Java代码中,我们通过定义接口并使用`@Select`, `@Insert`, `@Update`, `@Delete`等注解,或者直接继承SqlMapClientTemplate,来实现对数据库的操作。例如: ```java public interface UserService { @Select...

    Spring+Ibatis集成开发实例.doc

    在Spring和iBatis的集成开发中,我们通常利用Spring的IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)特性,结合iBatis的简单灵活的SQL映射功能,实现数据访问层的高效...

    IBatis2开发指南.pdf

    - **执行SQL**:使用`SqlMapClient`执行SQL语句,如`insert`、`update`、`delete`和`select`。 - **处理结果**:执行`select`语句后,IBatis会自动将结果集映射成Java对象。 ### OR映射 #### 1. 数据关联 IBatis...

    iBatis简单入门教程.

    2. 执行SQL:使用SqlSession的`selectList()`、`insert()`、`update()`或`delete()`方法执行SQL,根据需求传递参数。 3. 处理结果:对于查询操作,`selectList()`返回的是结果对象的列表;对于增删改操作,方法...

    iBATIS2.3-JavaDoc.rar

    1. SQL Maps:SQL映射文件是XML格式的,其中包含了数据库操作的定义,如INSERT、UPDATE、DELETE和SELECT语句。它们可以通过ID来引用,并且可以包含动态SQL元素,使得SQL语句可以根据传入的参数进行条件判断。 2. ...

    ibatis用xml配置文件配置使用

    在IT行业中,iBATIS(现为MyBatis)是一个非常流行的数据访问框架,它将SQL语句与Java代码分离,使得数据库操作更加简洁、灵活。本篇文章将深入探讨如何使用XML配置文件来配置iBATIS,以解决你在实际开发中可能遇到...

    ibatis jar包.zip

    例如,&lt;insert&gt;、、和&lt;select&gt;标签用于定义SQL操作。 3. **接口定义**:在业务逻辑层,开发者定义服务接口,这些接口的方法对应SQL映射文件中的SQL语句。通过实现这些接口,可以调用SQL执行数据库操作。 4. **数据...

    ibatis16个常用sql语句

    iBatis 16个常用SQL语句 iBatis是一个基于Java的持久层框架,提供了一个简洁的方式来访问和操作数据库。在iBatis中,SQL语句是通过XML文件来配置的。下面是16个常用的iBatis SQL语句,涵盖了基本的CRUD(Create、...

    ibatis-api.rar_ibatis a_ibatis api_ibatis api.chm_ibatisAPI_java

    Ibatis 是一个优秀的开源对象关系映射(ORM)框架,主要应用于Java开发中,它使得开发者...Ibatis-api.chm 文件很可能是Ibatis API 的离线帮助文档,包含了详细的API介绍和使用示例,对学习和使用Ibatis 非常有帮助。

    ibatis 开发指南.pdf

    5. 使用SqlSession执行SQL:在代码中通过SqlSessionFactory获取SqlSession实例,调用其方法执行SQL,如`selectOne()`, `selectList()`, `insert()`, `update()`, `delete()`等。 6. 数据库操作与事务控制:通过...

    struts2+iBatis+spring2.x入门实例

    DAO接口定义了数据库操作方法,而实现类通过`@Select`、`@Insert`、`@Update`、`@Delete`等注解指定SQL语句。 5. **视图**:Struts2支持多种视图技术,如JSP、FreeMarker等。视图负责展示数据,通常通过Struts2的`...

    ibatis-sqlmap-2.jar.zip

    《深入解析iBatis-SQLMap 2》 在Java Web开发领域,iBatis作为一个优秀的持久层框架,因其灵活性和高效性而深受开发者喜爱。本文将深入探讨iBatis-SQLMap 2版本,主要关注`ibatis-sqlmap-2.jar.zip`这个压缩包中的...

    Ibatis2.0注解示例.docx

    - 在Ibatis中,可以使用`@Select`、`@Insert`、`@Update`和`@Delete`注解在Service或DAO类的方法上,直接编写SQL查询。 6. **Struts2配置**: - Struts2的配置主要在`struts.xml`文件中,但通过注解也可以简化...

    Ibatis常用sql语句

    根据给定的文件信息,以下是对“Ibatis常用SQL语句”的详细解析,涵盖了一系列Ibatis在数据操作中的应用实例。 ### Ibatis简介 Ibatis是一个支持普通SQL查询、存储过程以及高级映射的优秀持久层框架。Ibatis可以让...

    Ibatis-api.rar_ibatis_ibatis api

    SqlSessionFactory是Ibatis的入口,它负责创建SqlSession对象,而SqlSession则用于执行SQL语句。在业务逻辑中,我们通常会通过Mapper接口与数据库进行交互,这些接口的定义与XML配置文件中的SQL语句相对应,这样就...

Global site tag (gtag.js) - Google Analytics