[菜鸟笔记]not in 优化实践问题

来源:互联网 发布:java底层框架源码 编辑:程序博客网 时间:2024/04/30 09:52

今天有在CSDN上查看一些关于NOT IN的效率优化,主要有参考
http://blog.csdn.net/anerou/article/details/5185573

对于下面一条sql
SELECT * FROM A WHERE A.ID NOT IN (SELECT B.ID FROM B)

优化方案有:

方法1:
select *
from emp a
where not exists ( select 1
from emp_bill b
where b.emp_no = a.emp_no)

方法2:
select a.*
from emp a ,emp_bill b
where a.emp_no=b.emp_no(+)
and b.emp_no is null

实践中,方案1操作成功,没有问题。原博说方案2效率最高,但是我在尝试方案2时却遇到了问题。

A表 A_STS=Y 表示成功记录

ID A_STS VALUE 1 Y 1 2 Y 2 3 Y 2 4 Y 2 5 2

B表 B_STS=00 表示成功记录

ID B_STS VALUE 1 00 1 2 00 2 3 2 4 00 2 5 5

要求查出A表中存在但B表中不存在的成功记录
SELECT * FROM A WHERE A.ID NOT IN (SELECT B.ID FROM B WHERE B.B_STS=’00’) AND A.A_STS=’Y’

两个表数据量均比较大,NOT IN跑哭了都没出结果。
于是我根据方法2写了下面一条sql,并很自然的加上了所需要的限制条件

select a.*       from A a ,B b       where a.id=b.id(+)             and b.id is null             and a.a_sts='Y'             and b._b_sts='00'

查询结果是 空

脑袋短路了很久,对几个条件分别注释后执行了几次
发现b.id is null 永远都不可能满足

其实最后的问题就是在 LEFT JOIN ON 与WHERE的优先级的问题,
我希望的结果是在成功记录中,筛选出B表中不存在的A表记录。而LEFT JOIN 是先关联,后滤表。

找到原因后,直接修改一下关联对象即可
select a.*
from A a ,(SELECT * FROM B WHERE B.B_STS=’00’) b
where a.id=b.id(+)
and b.id is null
and a.a_sts=’Y’

[基础问题,用得少想得少,也能坑死自己!]

0 0
原创粉丝点击