SQL中不可能让Where中的所有条件都走上索引, 不能走索引的部份条件就成了表上的filter条件, 在极端情况下, filter的顺序问题会影响SQL的执行结果. 例如我们建立这样一个表, 并输入两条数据.

create table TEST_FILTER
(
    COL1 NUMBER(10) NOT NULL,
    COL2 VARCHAR2(10) NOT NULL
);
INSERT INTO TEST_FILTER VALUES (1,’A');
INSERT INTO TEST_FILTER VALUES (2,’9′);

    然后分别在不同的优化器版本(可通过修改会话级optimizer features enable参数)下执行如下SQL语句, 会发现10g下这两个SQL都能返回正确的结果, 而在9i下, 第一个SQL会报不合法的数字(Invalid Number)的错误.

SELECT * FROM TEST_FILTER
    WHERE COL1=2 AND TO_NUMBER(COL2) < 100;
SELECT * FROM TEST_FILTER
    WHERE TO_NUMBER(COL2) < 100 AND COL1=2;

    观察一下两个SQL语句的执行计划, 区别只在于filter中的顺序问题.

filter(TO_NUMBER(“COL2″)<100 AND “COL1″=2)
filter(“COL1″=2 AND TO_NUMBER(“COL2″)<100)

    当出现第一个filter顺序时, SQL执行就出错了, 而在第二个时, SQL就能正确执行. Oracle 9i中filter的顺序会按从右到左执行, 而在10g中会先执行没有函数转换的过滤条件.