解决同一条sql在pl/sql工具中执行很快,在程序中却很慢

今天因为程序设计漏洞,把一张表得数据给truncate掉了,然后再重跑的过程中发现有一条sql再pl/sql工具执行很快(1秒内),程序中却需要200-300秒。
sql如下:

MERGE INTO t_qt_second t1
USING (select d.sn_no ,c.stair_org_id ,c.stair_org_name , a.assetpro_name , a.org_no , a.assetpro_no
		from t_org_sn a, t_device b, t_org_inf c , t_qt_second d
		where a.csn = b.dev_sn
		and a.org_no = c.idorganization
		and b.dev_sn = d.sn_no) t2
on (t1.sn_no = t2.sn_no)
WHEN MATCHED THEN
	UPDATE SET t1.stair_org_id = t2.stair_org_id , t1.stair_org_name = t2.stair_org_name ,
		t1.assetpro_name = t2.assetpro_name,t1.assetpro_no = t2.assetpro_no , t1.org_no = t2.org_no;

执行时间如图:
在这里插入图片描述
如图,sql是一条批量修改sql。再面向搜索引擎编程过程中发现一个关键字,PreparedStatement 。这位大佬说

一开始怀疑是语句使用UPER函数导致的,但是把语句修改为不使用函数也一样慢。。怀疑是使用了PreparedStatement 参数需要动态绑定问题,于是将PreparedStatement 改为Statement ,执行却很快

然而因为我们系统的封装太厚了,没法将PreparedStatement 改为 Statement。于是我在想虽然我整个sql没有参数绑定,但是我给他强行加一个固定参数绑定会不会有效果!于是sql就变成了这样

MERGE INTO t_qt_second t1
USING (select d.sn_no ,c.stair_org_id ,c.stair_org_name , a.assetpro_name , a.org_no , a.assetpro_no
		from t_org_sn a, t_device b, t_org_inf c , t_qt_second d
		where a.csn = b.dev_sn
		and a.org_no = c.idorganization
		and b.dev_sn = d.sn_no
		*and 1 = ${variable}*) t2
on (t1.sn_no = t2.sn_no)
WHEN MATCHED THEN
	UPDATE SET t1.stair_org_id = t2.stair_org_id , t1.stair_org_name = t2.stair_org_name ,
		t1.assetpro_name = t2.assetpro_name,t1.assetpro_no = t2.assetpro_no , t1.org_no = t2.org_no

可以看到在t2表 条件的最后我加了一个 and 1 = ${variable},其中variable变量在程序里面设置的是 1,然后再放到服务器上重跑一下。
!!!!!
再来看下执行时间!!!
在这里插入图片描述
终于舒服了~~~~~~

题外话:
这个应该和我们系统的破框架有关系,这个框架会存储程序运行过程中(变量、sql查询等一系列和数据有关系的操作)的数据以节点树的形式存储在树上(具体是什么树也没有研究过,框架封装太厚,看不到)。
以下是我对这破框架的猜想:
所以存在每一条sql运行过程中,会去扫描整个树中有没有某个节点是sql的绑定参数。才导致这种没有参数绑定的sql在程序上执行特别慢。

另外
如果有同样问题的朋友,并且你们是使用的mybatis,可以检查下自己动态绑定的参数 和 数据库中对应字段的 类型是不是一致。比如代码中给的类型是string,但是数据库中该字段是int,这样也可能会导致在工具上执行快,程序中很慢的情况。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值