« SQL执行filter条件的顺序问题 »
DBA » http://www.anysql.net/dba/oracle-where-filter-order.html 2009-07-09SQL中不可能让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中会先执行没有函数转换的过滤条件.


有人写了这样的语句, 然而B这个表没有COL1这个列.
delete /*+rule*/ from A
where COL1 in (select COL1 from B);
结果是A表的记录全部被删除, 的确是要小心Review SQL.
haha,半年前解决过一个和你一样的问题