爬坑日记
这两天遇到一个很“无语”的业务逻辑,本身sql也是不难的,但是搞了两三天(自己一上来理解错了),最后遇到好心大佬的帮助指点迷津,顺便详细给我讲解了一下以前没用过的exists关键字,真是万分感谢!!!
事情是这样的:
一开始直接下意识xian无脑写了个in操作(不要关注逻辑,后面会摊牌...),然后执行了一下发现居然需要4秒?虽然是个设计有点不合理数据百万级的数据库也不至于查询一下4秒啊,遇是带着疑惑开始了爬坑之旅。
--------->
首先呢是想到了 in 操作效率太低,不能走索引,所以就换成了内连接。
--------->
看看结果
沉思良久,,,in操作可能在结果集比较大的时候性能较低,但是我这种结果集并不大的业务情境下(细心的可以看一下where后面有个只筛选当月数据),如果是结果集并不大,那么inner join反而在查询中途笛卡尔积的过程消耗极大的性能(当前数据库是百万级别的数据库)
---难道就没别的办法了?---
先是度娘看了一堆sql调优注意事项,然后没找到有用的东西,最后一波explain操作得到如下结果:
oh no!!! 结果已经很明显了,没走索引?
然后大佬提出让我试试exists,结果一个很尴尬的问题,我之前根本没用过exists关键字,简单看了下和in的对比,直接把exists改成in就以为结束了。结果一执行发现所有条件都为true了???????????
这可触及到知识盲区了,看了很多博客都没理解到它的意思,最后还是在大佬的帮助下,理解了该关键字的作用。
个人理解:
- exists里面主要是是判断存不存在,并不是要你select个什么东西出来,直接select 1就行。
- 外层会拿每一层和exists里面的条件做比较,如果成功则记录下来,失败则下一条循环,以此类推
- 那么根据上一点,可以注意了,几乎会有个固定写法 where 会添加一个条件 and a.id = b.id,如果说没有这个条件,那么无论拿哪条外层的记录来对比条件都是正确的,所有这个时候所有的记录都能匹配成功了(重点!!!)
- 也可以说exists的意义就是为了让这个内部的sql脱离外层sql就不能单独执行
最后看业务发现根本不必如此麻烦,因为是在单表中,直接很简单的update就能完成逻辑......可能是一开始头有点蒙吧,一上来写了个in操作,就一直在里面爬坑了,不过总的来说收货还是有的。最后附上一张exists的用法