【问题标题】:How to improve the SQL performance from my Java application如何提高我的 Java 应用程序的 SQL 性能
【发布时间】:2016-07-01 15:41:42
【问题描述】:

我有这个问题:

我有一个用 java(Spring 框架)开发的旧的大型应用程序。问题是一个 sql 查询,当我从 Java 应用程序执行它时,它需要很长时间,这与我从 Sql Developer 执行它时不同。 从 Java 大约需要 7 分钟。从 Sql Developer 需要 30 秒。两种情况下的查询都是一样的。

应用程序配置为:

  • JDK 1.6
  • OJDBC 6
  • Spring 框架 3.6
  • Oracle 11g 企业版 11.2.0.3.0 版

数据源配置:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driverClassName}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="initialPoolSize" value="${jdbc.initialPoolSize}"/>
    <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
    <property name="minPoolSize" value="${jdbc.minPoolSize}"/>
</bean>

最后,我使用 IBATIS 2.3 进行 sql 映射。

我做了一个测试调试,当 DAO 类调用 Ibatis 映射(查询)时,性能开始变慢。

一些帮助?

对不起我的英语。

问候

更新 1:

查询:

SELECT PAG.ID_PAG AS ID_PAG, CAD.CAD_NOMBRE AS CAD_NOMBRE, LOC.LOC_NOMBRE AS LOC_NOMBRE, EMI.EMI_CODIGO AS EMI_CODIGO, EMI.EMI_NOMBRE AS EMI_NOMBRE, TO_CHAR(PAG.PAG_FECHA, 'DD/MM/YYYY') AS TRX_FECHA, PAG.PAG_POS AS TRX_POS, RTRIM(PAG.PAG_COMPROBANTE) AS TRX_COMPROBANTE, 1 AS CANTIDAD, PAG.PAG_MONTO AS TRX_MONTO, PAG.PAG_COMISION_TOTAL AS MONTO_COMISION, PAG.PAG_NETO_TOTAL AS MONTO_NETO FROM PW_PAGO PAG, PW_LOCAL LOC, PW_EMISOR EMI, PW_CADENA CAD, PW_TIPOTRX_EMI TTE WHERE CAD.ID_CADENA = PAG.ID_CADENA AND EMI.ID_EMISOR = PAG.ID_EMISOR AND LOC.ID_LOCAL = PAG.ID_LOCAL AND PAG.ID_TIPOTRX_EMI = TTE.ID_TIPOTRX_EMI AND PAG.PAG_FLAG_COMISION = 'S' AND PAG.PAG_FECHA >= TO_DATE('20160501','YYYYMMDD') AND PAG.PAG_FECHA <= TO_DATE('20160503','YYYYMMDD') ORDER BY CAD.CAD_NOMBRE, LOC.LOC_NOMBRE, EMI.EMI_NOMBRE, TO_CHAR(PAG.PAG_FECHA, 'DD/MM/YYYY'), PAG.PAG_POS, PAG.PAG_COMPROBANTE, PAG.PAG_MONTO

更新 2:这是 Ibatis 配置:

<?xml version="1.0" encoding="UTF-8"?>

<resultMap id="getPagosComisionesSinGrupoDetalle"
           class="cl.bbr.portalweb.dto.InformePagosComisionesSinGrupoDetalleDTO" >

    <result column="ID_PAG"             property="id_pag"           jdbcType="INTEGER" />
    <result column="CAD_NOMBRE"         property="cad_nombre"       jdbcType="VARCHAR" />
    <result column="LOC_NOMBRE"         property="loc_nombre"       jdbcType="VARCHAR" />
    <result column="EMI_CODIGO"         property="emi_codigo"       jdbcType="VARCHAR" />
    <result column="EMI_NOMBRE"         property="emi_nombre"       jdbcType="VARCHAR" />       
    <result column="TRX_FECHA"          property="trx_fecha"        jdbcType="DATE" />
    <result column="TRX_POS"            property="trx_pos"          jdbcType="VARCHAR" />
    <result column="TRX_COMPROBANTE"    property="trx_comprobante"  jdbcType="VARCHAR" />
    <result column="CANTIDAD"           property="cantidad"         jdbcType="INTEGER" />
    <result column="TRX_MONTO"          property="trx_monto"        jdbcType="DECIMAL" />
    <result column="MONTO_COMISION"     property="monto_comision"   jdbcType="DECIMAL" />
    <result column="MONTO_NETO"         property="monto_neto"       jdbcType="DECIMAL" />
</resultMap>

<!-- Obtiene datos comisiones sin grupo y con detalle-->
<select id="getPagosComisionesSinGrupoDetalle"
        resultMap="getPagosComisionesSinGrupoDetalle"
        parameterClass="cl.bbr.portalweb.dto.InformePagosComisionesSearchCriteria">
    SELECT  PAG.ID_PAG AS ID_PAG, CAD.CAD_NOMBRE AS CAD_NOMBRE, LOC.LOC_NOMBRE AS LOC_NOMBRE,  EMI.EMI_CODIGO AS EMI_CODIGO,EMI.EMI_NOMBRE AS EMI_NOMBRE, TO_CHAR(PAG.PAG_FECHA, 'DD/MM/YYYY') AS TRX_FECHA, PAG.PAG_POS AS TRX_POS, RTRIM(PAG.PAG_COMPROBANTE) AS TRX_COMPROBANTE, 1 AS CANTIDAD,PAG.PAG_MONTO AS TRX_MONTO, PAG.PAG_COMISION_TOTAL AS MONTO_COMISION,PAG.PAG_NETO_TOTAL AS MONTO_NETO FROM PW_PAGO PAG, PW_LOCAL LOC,PW_EMISOR EMI, PW_CADENA CAD, PW_TIPOTRX_EMI TTE WHERE CAD.ID_CADENA =PAG.ID_CADENA AND EMI.ID_EMISOR = PAG.ID_EMISOR AND LOC.ID_LOCAL = PAG.ID_LOCAL        AND PAG.ID_TIPOTRX_EMI = TTE.ID_TIPOTRX_EMI AND PAG.PAG_FLAG_COMISION = 'S'              AND <![CDATA[PAG.PAG_FECHA >= #f_ini#]]> AND <![CDATA[PAG.PAG_FECHA <= #f_fin#]]> ORDER BY CAD.CAD_NOMBRE, LOC.LOC_NOMBRE, EMI.EMI_NOMBRE, TO_CHAR(PAG.PAG_FECHA, 'DD/MM/YYYY'), PAG.PAG_POS, PAG.PAG_COMPROBANTE, PAG.PAG_MONTO
    </select>

Ibatis 地图配置:

<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> <sqlMapConfig>
<settings useStatementNamespaces="true"/> 
<sqlMap resource="cl/bbr/portalweb/dao/ibatis/maps/oracle/FINDER_INFORME_PAGOS_COMISIONES_SqlMap.xml"/> </sqlMapConfig>

【问题讨论】:

  • 这个问题很笼统,你至少应该提供一些细节。您是否以任何形式使用缓存?您是否尝试过创建数据库索引?
  • 查询在哪里?
  • 如果您想调整有问题的查询,请将其附加到问题中。
  • 请包含Ibatis映射xml和映射类。
  • 所有这些点都有助于改善 Java 中的查询时间吗?为什么来自 SQL 开发人员的速度要快得多? (30 秒)与 7 分钟的应用程序? @AleksG

标签: java sql spring oracle jdbc


【解决方案1】:

将您选择的fetchSize 参数设置为较大的值,例如1000:

<select id="getPagosComisionesSinGrupoDetalle"
    resultMap="getPagosComisionesSinGrupoDetalle"
    parameterClass="cl.bbr.portalweb.dto.InformePagosComisionesSearchCriteria"
    fetchSize="1000">
SELECT  PAG.ID_PAG AS ID_PAG, CAD.CAD_NOMBRE AS CAD_NOMBRE, LOC.LOC_NOMBRE AS LOC_NOMBRE,  EMI.EMI_CODIGO AS EMI_CODIGO,EMI.EMI_NOMBRE AS EMI_NOMBRE, TO_CHAR(PAG.PAG_FECHA, 'DD/MM/YYYY') AS TRX_FECHA, PAG.PAG_POS AS TRX_POS, RTRIM(PAG.PAG_COMPROBANTE) AS TRX_COMPROBANTE, 1 AS CANTIDAD,PAG.PAG_MONTO AS TRX_MONTO, PAG.PAG_COMISION_TOTAL AS MONTO_COMISION,PAG.PAG_NETO_TOTAL AS MONTO_NETO FROM PW_PAGO PAG, PW_LOCAL LOC,PW_EMISOR EMI, PW_CADENA CAD, PW_TIPOTRX_EMI TTE WHERE CAD.ID_CADENA =PAG.ID_CADENA AND EMI.ID_EMISOR = PAG.ID_EMISOR AND LOC.ID_LOCAL = PAG.ID_LOCAL        AND PAG.ID_TIPOTRX_EMI = TTE.ID_TIPOTRX_EMI AND PAG.PAG_FLAG_COMISION = 'S'              AND <![CDATA[PAG.PAG_FECHA >= #f_ini#]]> AND <![CDATA[PAG.PAG_FECHA <= #f_fin#]]> ORDER BY CAD.CAD_NOMBRE, LOC.LOC_NOMBRE, EMI.EMI_NOMBRE, TO_CHAR(PAG.PAG_FECHA, 'DD/MM/YYYY'), PAG.PAG_POS, PAG.PAG_COMPROBANTE, PAG.PAG_MONTO
</select>

Oracle JDBC 驱动程序的默认值非常低,因此与服务器的来回流量很大。

【讨论】:

  • 感谢您的回答,我试过了,但它并没有提高性能@kbolino
  • 为了理智,您是否尝试过使用普通 JDBC 从 Java 运行查询?
猜你喜欢
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-21
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
相关资源
最近更新 更多