not in效率低(MYSQL的Not IN、not EXISTS如何优化)

  • 【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】
  • 【创作不易,点个赞就是对我最大的支持】

前言

仅作为学习笔记,供大家参考
总结的不错的话,记得点赞收藏关注哦!

目录

    • 前言
      • 原SQL使用的是NOT IN
      • 新SQL使用的是NOT EXISTS
      • 结果:效率提升十倍不止

原SQL使用的是NOT IN

       select a.id, b.messageId, a.sourceTypeId, a.title, a.messageTime, a.depId, a.status, b.setMark, b.msgType, b.msgRemarks
      from t_sync_data a left join t_message_seting b on a.id = b.messageId where exists (select 1 from t_sync_data where depId=136 and
        status!=4 and status!=2 and status!=5)
        <if test="messageIds != null and messageIds.size() >0"> and a.id NOT IN
            <foreach item="messageId" collection="messageIds" open="(" separator="," close=")">
                #{messageId}
            </foreach>
        </if>
       order by a.messageTime desc, a.id desc, a.status

原因分析:我用了两条sql来解决,第一条sql去查了一组id来排除数据,导致每次查询都要去遍历
建议:能用1条sql出来还是用一条会更快,尽量不要用IN 、NOT IN
1、用 EXISTS 或 NOT EXISTS 代替
2、用JOIN 代替
这里我只查子表主表都存在的数据,故用了内连接,也可以用右连接,需求是以副表为主

新SQL使用的是NOT EXISTS

这里要注意一下:not exists子查询要加一个条件:messageId=a.id 和外边的表关联起来,否则是查不到数据的

select a.id, b.messageId, a.sourceTypeId, a.title, a.messageTime, a.depId, a.status, b.setMark, b.msgType, b.msgRemarks
        from t_sync_data a inner join t_message_seting b on a.id = b.messageId where a.depId=136 and  a.status!=4 and a.status!=2 and a.status!=5
        and not EXISTS (select id
        from t_message_task WHERE  messageId=a.id
        <if test="depId != null ">and depId = #{depId}
         )
        order by a.messageTime desc, a.id desc, a.status 

结果:效率提升十倍不止

创作不易,点个赞就是对我最大的支持~


wxgzh:程序员温眉

CSDN:程序员温眉

每天进步一点点的程序员

你可能感兴趣的:(mysql,sql,数据库)