Mysql多表联查使用union all 代替or查询

多表联查注意点:

 

ACT_RU_TASK  表数据量:19767

ACT_HI_PROCINST  表数据量:21607

BPM_HI_ROLETASKINST  表数据量:1911

BPM_HI_ROLEIDENTITYLINK  表数据量:1229

 

所有的查询sql、所有的表结构及数据详情见附件。

所有的查询sql、所有的表结构及数据详情见附件(百度云网盘:链接: https://pan.baidu.com/s/1Jte1GykJBK9TJ1NyQTMzug  密码: vvja

)。

1.Sql多表联查如果只使用and的话,可以直接使用join系列。

   比如:整个查询速度还是可以的,大约0.041s

      

SELECT

        RES.*

        FROM

            ACT_RU_TASK RES

            INNER JOIN ACT_HI_PROCINST HPI ON RES.PROC_INST_ID_ = HPI.ID_

            LEFT JOIN BPM_HI_ROLETASKINST as BHR  on  BHR.TASKID = RES.ID_

            INNER JOIN BPM_HI_ROLEIDENTITYLINK I ON I.TASK_ID = RES.ID_

        WHERE

            HPI.STATUS_ !=0

            AND RES.ASSIGNEE_ IS NULL

            AND I.USER_TYPE = 'candidate'

            AND (I.USER_LDAP ="xiaoyuhan" and I.USER_INDEX != "xiaoyuhan")

        ORDER BY

            RES.CREATE_TIME_ DESC

            LIMIT 200 OFFSET 0

 

 

 

2.Sql多表联查如果只会使用到or过滤的话,不要直接使用join系列

   比如:使用join并且使用or来过滤join表中的的某个字段如下,整个查询时间大约3.833s,因此不推荐这样用。

       

SELECT

         DISTINCT   RES.*

        FROM

            ACT_RU_TASK RES

            INNER JOIN ACT_HI_PROCINST HPI ON RES.PROC_INST_ID_ = HPI.ID_

            INNER JOIN ACT_RU_IDENTITYLINK I ON I.TASK_ID_ = RES.ID_

        --  left join BPM_HI_ROLETASKINST as bhr  on  bhr.taskId = RES.ID_

            LEFT JOIN BPM_HI_ROLEIDENTITYLINK as BHRL on  BHRL.TASK_ID =RES.ID_

        WHERE

            HPI.STATUS_ !=0

            AND RES.ASSIGNEE_ IS NULL

            AND I.TYPE_ = 'candidate'

            AND (I.USER_ID_ ="xiaoyuhan"  or BHRL.user_ldap ="xiaoyuhan")

        ORDER BY

            RES.CREATE_TIME_ DESC

            LIMIT 200 OFFSET 0

 

 

 

  1)可以使用union代替or查询,整个查询时间大约0.193s,就快了很多。

      

SELECT

        DISTINCT RES.*

        FROM

            ACT_RU_TASK RES

            INNER JOIN ACT_HI_PROCINST HPI ON RES.PROC_INST_ID_ = HPI.ID_

            INNER JOIN ACT_RU_IDENTITYLINK I ON I.TASK_ID_ = RES.ID_

        --  LEFT JOIN (SELECT ASSIGNEE_,ID_ FROM ACT_RU_TASK UNION  SELECT USER_LDAP,TASKID FROM BPM_HI_ROLETASKINST) AS BHR ON BHR.ID_=RES.ID_

            LEFT JOIN (SELECT USER_ID_,TASK_ID_ FROM ACT_RU_IDENTITYLINK UNION   SELECT USER_LDAP,TASK_ID FROM BPM_HI_ROLEIDENTITYLINK) as BHRL on  BHRL.TASK_ID_ =RES.ID_

        WHERE

            HPI.STATUS_ !=0

            AND RES.ASSIGNEE_ IS NULL

            AND I.TYPE_ = 'candidate'

            AND (BHRL.USER_ID_ ="xiaoyuhan")

        ORDER BY

            RES.CREATE_TIME_ DESC

            LIMIT 200 OFFSET 0

 

 

 

  2)union all  大部分是比union更快的,但是不会去重,此处由于查询不符和查询目的,因此查询时间可能会更长一些,整个查询时间大约0.340s

       

SELECT

            DISTINCT RES.*

        FROM

            ACT_RU_TASK RES

            INNER JOIN ACT_HI_PROCINST HPI ON RES.PROC_INST_ID_ = HPI.ID_

            INNER JOIN ACT_RU_IDENTITYLINK I ON I.TASK_ID_ = RES.ID_

        --  LEFT JOIN (SELECT ASSIGNEE_,ID_ FROM ACT_RU_TASK UNION  SELECT USER_LDAP,TASKID FROM BPM_HI_ROLETASKINST) AS BHR ON BHR.ID_=RES.ID_

            LEFT JOIN (SELECT USER_ID_,TASK_ID_ FROM ACT_RU_IDENTITYLINK UNION all  SELECT USER_LDAP,TASK_ID FROM BPM_HI_ROLEIDENTITYLINK) as BHRL on  BHRL.TASK_ID_ =RES.ID_

        WHERE

            HPI.STATUS_ !=0

            AND RES.ASSIGNEE_ IS NULL

            AND I.TYPE_ = 'candidate'

            AND (BHRL.USER_ID_ ="xiaoyuhan")

        ORDER BY

            RES.CREATE_TIME_ DESC

            LIMIT 200 OFFSET 0

 

 

 

   3)整体的union all两个子select,比left 单个表最后where还要快,这是速度最快的,整个查询时间大约0.044s(非常推荐)。

            

(SELECT

            RES.*

        FROM

            ACT_RU_TASK RES

            INNER JOIN ACT_HI_PROCINST HPI ON RES.PROC_INST_ID_ = HPI.ID_

            INNER JOIN ACT_RU_IDENTITYLINK I ON I.TASK_ID_ = RES.ID_

        WHERE

            HPI.STATUS_ != 0

            AND RES.ASSIGNEE_ IS NULL

            AND I.TYPE_ = 'candidate'

            AND ( I.USER_ID_ = "xiaoyuhan" )

        )

        UNION ALL

            (SELECT

            RES.*

        FROM

            ACT_RU_TASK RES

            INNER JOIN ACT_HI_PROCINST HPI ON RES.PROC_INST_ID_ = HPI.ID_

            LEFT JOIN BPM_HI_ROLETASKINST as BHR  on  BHR.TASKID = RES.ID_

            INNER JOIN BPM_HI_ROLEIDENTITYLINK as BHRL on  BHRL.TASK_ID =RES.ID_

        WHERE

            HPI.STATUS_ !=0

            AND RES.ASSIGNEE_ IS NULL

            AND BHRL.USER_TYPE = 'candidate'

            AND (BHRL.USER_LDAP ="xiaoyuhan" and BHRL.USER_INDEX != "xiaoyuhan")

        )

            ORDER BY

            CREATE_TIME_  DESC

            LIMIT 200 OFFSET 0

           

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用中提到的优化方法,对于使用or的查询,在某些情况下可以使用union或者union all来代替以获得更好的效果。使用union或者union all的方式可以避免索引失效的问题,提高查询速度。 使用union或者union all的方式进行查询时,可以将原来的or条件拆分成多个子查询,并使用union或者union all将它们合并在一起。例如,将原来的查询语句SELECT id FROM A WHERE num =10 or num = 20可以改写为: SELECT id FROM A WHERE num = 10 union all SELECT id FROM A WHERE num = 20 这样的查询可以更有效地利用索引,提高查询速度。根据引用和引用的描述,使用union all的方式可能会比使用union更快,但是不会去重。所以根据实际的查询需求,可以选择使用union或者union all。 总结起来,为了提高or查询的效率,可以尽量使用union或者union all来代替,将or条件拆分成多个子查询并合并起来。这样可以避免索引失效,并且根据需求选择使用union或者union all。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Mysql多表联查使用union all 代替or查询](https://blog.csdn.net/CSxiaoyuhan/article/details/108583308)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Sql优化总结](https://blog.csdn.net/qq_39134704/article/details/124594529)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值