7. 由于优化工具处理“或”逻辑可能有问题,所以尽量采用其他方式重写
尽可能分离谓词。下面的例子可以说明这一点:
- SELECT DEPTNO, DEPTNAME
- FROM DEPT
- WHERE (ADMRDEPT = 'E01'
- AND DEPTNAME LIKE 'BRANCH%')
- OR (DEPTNO = 'D01'
- AND DEPTNAME LIKE 'BRANCH%')
也可以写作:
- SELECT DEPTNO, DEPTNAME
- FROM DEPT
- WHERE (ADMRDEPT = 'E01' OR
- DEPTNO = 'D01')
- AND DEPTNAME LIKE 'BRANCH%'
这里的关键是:可以看到这两个例子有相同的逻辑。
很多情况下,这会使优化工具从不可索引谓词转移到可索引的谓词,或者可能使优化工具选择一个多索引处理访问路径,也可能不再选择多索引处理。用“或”(OR)逻辑连接两个谓词会创建非布尔项谓词,这意味着即使某个谓词为false,也不能因此完全消除一行,所以通常最好避免用OR连接谓词。也许一个谓词为false,但另一个可能是true。相比之下,使用“与”(AND)逻辑来连接谓词通常更为高效。不过,在这种情况下,它能为优化工具提供更多选择。
如果谓词用 “OR”连接,首先要把谓词写为与表中最大数目的行匹配,这很重要。因为一旦某一行满足条件,OR列表中的谓词计算就会结束。
用OR逻辑连接简单谓词时,得到的复合谓词会在简单谓词第1阶段或第2阶段中相对高的阶段完成计算。例如:
- SELECT EMPNO, LASTNAME, SALARY
- FROM EMP
- WHERE WORKDEPT = 'D01' -- Stage 1 Indexable
- OR EDLEVEL <> 16 -- Stage 1 Non Indexable
由于第二个谓词是一个Stage 1不可索引谓词,而另一个简单谓词是一个Stage 1可索引谓词,所以整个复合谓词会成为一个Stage 1不可索引谓词:
- SELECT EMPNO, LASTNAME, SALARY
- FROM EMP
- WHERE WORKDEPT = 'D01' -- Stage 1 Indexable
- OR YEAR(HIREDATE ) = 1990 -- Stage 2
由于第二个谓词是一个Stage 2不可索引谓词,而另一个简单谓词是一个Stage 1可索引谓词,所以整个复合谓词是一个Stage 2不可索引谓词。