exists与in等价情形分析

mybatis中对sql进行了分支判断,不同逻辑走不同子查询 sql如下

1、使用exists,其中in里面约1w数据

select   
count( distinct  vehicle.id) 
 FROM  base_server.t_vehicle vehicle
         
            inner join base_server.t_fleet_vehicle fleet on fleet.vehicle_id=vehicle.id
         
         
         WHERE  (1=1
                                      
                            and exists (select tfv.vehicle_id from base_server.t_fleet_vehicle tfv where
                            tfv.fleet_id in
                            (
                               xxx
                )
            and vehicle.del_flag=0 
               order by vehicle.create_time desc, vehicle.id desc           
            limit 20 offset 0;

2、使用in

select   
count(distinct vehicle.id)
 FROM  t_vehicle vehicle INNER JOIN t_fleet_vehicle fleet on fleet.vehicle_id=vehicle.id         
         WHERE  (1=1          
                        )
                and vehicle.tenant_id=1
                and vehicle.app_id=10301
                and fleet.fleet_id in
                (xxx)
            and vehicle.del_flag=0 
 group by vehicle.id
               order by vehicle.create_time desc, vehicle.id desc

            limit 20 offset 0;

3、业务分析

以上两个sql在代码中是一个sql,通过条件判断不同分支成为两个sql,在适配达梦数据库,尽量减少对代码的修改,不优化前需要7-8s 首先在数据库测尝试优化。

尝试对sql进行优化,通过hint控制第一个sql走hash连接快,第二个sql走索引连接快,对于代码侧无法做到兼顾。仔细观察这两个sql逻辑上是等价的,通开发沟通再次确认后确实等价,第二个sql消耗资源小,速度更快,建议使用第二个,此问题得到解决

4、总结

此sql优化并不难,主要是如何减少换数据库对代码的通用性,如果只是聚焦sql本身,此sql很难兼顾两种不同子查询情形优化,从业务角度梳理逻辑来优化有时更为省力。

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值