日期:2014-05-16 浏览次数:20640 次
以前在网上看到一些观点,in 或者not in 都不会用到索引,昨天在优化sql的时候,发现这些观点并不对
?
SELECT *
FROM WF_DOC_GW_FAWEN F
WHERE F.CFBT = 'ee' AND
F.NDOCID IN (SELECT DISTINCT GI.SRC_NDOCID
FROM WF_DOC_GW_INNER GI,
WF_DOC_GW GW
WHERE GI.NDOCID = GW.NDOCID AND
INSTR(', ' || GW.CPROCUSERLIST || ', ',
', ' || TO_CHAR(45901) || ', ') > 0 AND
GI.RETURNSTATUS IS NULL AND
GI.SRC_NDOCID IS NOT NULL)
?
?
从上面的执行计划中可以看到WF_DOC_GW_FAWEN的NDOCID字段在执行in的操作中用到了索引,如果子查询的记录数超过一定数量,in的操作也就不会用到索引了。
如果把in或为not in,WF_DOC_GW_FAWEN的NDOCID字段是不会用到索引的,不管子查询的数量是多还是少,但是出现了另外一种情况,WF_DOC_GW_INNER的SRC_NDOCID字段用到了索引,如下
SELECT *
FROM WF_DOC_GW_FAWEN F
WHERE F.CFBT = 'ee' AND
F.NDOCID NOT IN (SELECT DISTINCT GI.SRC_NDOCID
FROM WF_DOC_GW_INNER GI,
WF_DOC_GW GW
WHERE GI.NDOCID = GW.NDOCID AND
INSTR(', ' || GW.CPROCUSERLIST || ', ',
', ' || TO_CHAR(45901) || ', ') > 0 AND
GI.RETURNSTATUS IS NULL AND
GI.SRC_NDOCID IS NOT NULL)
?
由此推断,oracle在解析,编译sql语句的时候,对我们写的sql进行了变换,把子查询的字段和主查询的字段进行了关联