同一条sql,为什么在脚本上运行比在java应用运行快多了

同一条sql同一个数据库,为什么在脚本上运行比在java应用运行快多了(springboot+mybatis+sqlserver)
java sql监考:

img

sqlserver脚本执行这条sql只需要1s不到,而java应用上要10s,执行该接口无其它业务,而且同环境下其它接口效率正常

使用相同的参数单独调用接口看下耗时,是不是有可能当时有别的SQL查询相关表导致。


select si.xm as name, si.xh, d.name as bjmc, si.xymc, i.chg_year as chgYear, i.chg_type as chgType,
               i.account as payable, (isnull(fi.fact_account, 0) - isnull(rf.re_account, 0)) as payin,
               (isnull(i.account, 0) - isnull(fi.fact_account, 0) + isnull(rf.re_account, 0)) as payout,
               '--' as payMode
    from (select xh, chg_year, chg_type, account from Stu_Chg_Info where chg_year > #{xn,jdbcType=VARCHAR}) i
    left join Stu_Fact_Chg_Info fi on (i.xh = fi.xh and i.chg_type = fi.chg_type and i.chg_year = fi.chg_year and isnull(fi.djzt, 0) = 0)
    left join Re_Fact_Chg rf on (i.xh = rf.xh and i.chg_type = rf.chg_type and i.chg_year = rf.chg_year and isnull(rf.djzt, 0) = 0)
    left join Stu_Info si on (i.xh = si.xh and si.xn >= #{xn,jdbcType=VARCHAR})
    left join department d on si.bjdm = d.code
    <where>
       <if test="zjh != null and zjh != ''">and (si.xh = #{zjh,jdbcType=VARCHAR} or si.xm = #{zjh,jdbcType=VARCHAR} or si.sfzh = #{zjh,jdbcType=VARCHAR})</if>
       <if test="chgYear != null and chgYear != ''">and i.chg_year = #{chgYear,jdbcType=VARCHAR}</if>
       <if test="chgType != null and chgType != ''">and i.chg_type = #{chgType,jdbcType=VARCHAR}</if>
       <if test="payItems != null and payItems.length != 0">
          and i.chg_type in
          <foreach collection="payItems" open="(" close=")" item="item" separator=",">
            #{item,jdbcType=VARCHAR}
          </foreach>
       </if>
       <if test="startDate != null">fi.datetime &gt;= #{startDate,jdbcType=TIMESTAMP}</if>
       <if test="endDate != null">fi.datetime &lt;= #{endDate,jdbcType=TIMESTAMP}</if>
    </where>
    order by si.xymc, si.bjdm, si.xh, i.chg_year desc, i.chg_type

应用上的SQL日志贴下

数据库有自己的缓存机制吧,mybatis解析xml中的逻辑判断也要时间,网络等问题也会影响java连接数据库的速度,理论上来说应该不会有十倍这么大的差异,你可以把where后边条件都给去掉,看看是不是还得十多秒

以下内容部分参考ChatGPT模型:


可能的原因有:

  1. 网络延迟:Java应用和数据库之间的网络延迟比脚本执行的本地数据库要高,这可能导致Java应用的执行速度变慢。

  2. 数据库链接池:Java应用使用的数据库链接池可能不够优化,导致在执行查询时需要等待可用的链接,从而导致执行速度变慢。

  3. SQL优化:脚本执行和Java应用执行的SQL语句可能不同,或者Java应用执行的SQL语句没有进行优化,导致执行速度变慢。

解决思路:

  1. 确认网络延迟问题是否存在,可以使用ping命令或者traceroute命令检查网络延迟情况。

  2. 确认数据库链接池是否优化,可以检查Java应用的数据源配置,例如是否开启了缓存,是否使用了连接池。

  3. 确认SQL语句是否优化,可以使用数据库的查询分析工具,例如SQL Server的查询分析器,来分析SQL语句的执行计划,找出性能瓶颈所在,并进行优化。例如添加索引、避免使用子查询等。

示例代码:

  1. 检查网络延迟
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("ping -c 3 " + dbHost);
int exitValue = process.waitFor();
if (exitValue == 0) {
    System.out.println("Ping成功");
} else {
    System.out.println("Ping失败");
}
  1. 检查数据库链接池
<!-- 数据源配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/test" />
    <property name="username" value="root" />
    <property name="password" value="123456" />
    <property name="maxActive" value="50" />
    <property name="maxIdle" value="10" />
    <property name="maxWait" value="5000" />
</bean>
  1. SQL语句优化
-- 查询分析器
SET SHOWPLAN_TEXT ON;
SELECT * FROM table WHERE id = 1;
SET SHOWPLAN_TEXT OFF;

如果我的建议对您有帮助、请点击采纳、祝您生活愉快