select* from temp where a = 1 and b = 2 and c= 3 and  d= 4 ;
想知道where 是从 a 往 d 执行的,还是d 往 a 这边执行的。

解决方案 »

  1.   


    ------测试了下,从左往右执行。。呵呵。
    SQL> select * from dual where 1?=2 and 1=1 and 3?=2;
    select * from dual where 1?=2 and 1=1 and 3?=2
                              *
    第 1 行出现错误:
    ORA-00911: 无效字符
      

  2.   

    解析顺序和执行顺序未必是一样的。从上边的实验看,解析 似乎是由左向右。
    不知道oracle是否对and谓词执行顺序可以动态调整,如果是那样,就更无定论了。
      

  3.   

    --解析都是从右往左解析的
    scott@YPCOST> SELECT * FROM DEPT WHERE DEPTNOQ=10 AND LOCT='BOSTON';
    SELECT * FROM DEPT WHERE DEPTNOQ=10 AND LOCT='BOSTON'
                                            *
    第 1 行出现错误:
    ORA-00904: "LOCT": 标识符无效
    --上面where条件的两个字段名都是错误的 提示loct无效scott@YPCOST> SELECT * FROM DEPT WHERE DEPTNO1=10 AND LOC='BOSTON';
    SELECT * FROM DEPT WHERE DEPTNO1=10 AND LOC='BOSTON'
                             *
    第 1 行出现错误:
    ORA-00904: "DEPTNO1": 标识符无效
    --上面where条件的loc字段是正确的 提示deptno1无效scott@YPCOST> SELECT * FROM DEPT WHERE DEPTNO1=10 OR LOC='BOSTON';
    SELECT * FROM DEPT WHERE DEPTNO1=10 OR LOC='BOSTON'
                             *
    第 1 行出现错误:
    ORA-00904: "DEPTNO1": 标识符无效
    scott@YPCOST> SELECT * FROM DEPT WHERE DEPTNO1=10 OR LOCA='BOSTON';
    SELECT * FROM DEPT WHERE DEPTNO1=10 OR LOCA='BOSTON'
                                           *
    第 1 行出现错误:
    ORA-00904: "LOCA": 标识符无效
      

  4.   

    Oracle采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾按照这个说法 应该是 从右向左的
      

  5.   

    oracle 根据优化器的配置,自动进行调整!
      

  6.   

    sql92 是左到右  sql99右到左都是把数据量大的过滤条件放到最后面(右)
      

  7.   

    从右到左…
    如果表上有索引例如索引顺序( a,b,c) 那么 尽量写成 where a =?  and b= ? and c= ? and d = ?好像oracle9之后 顺序写反了 ORACLE也能利用到索引, 但是还是需要花费一定的时间,所以还是一次写好的好.尽量把能过滤的大条件写在后面 如标志,男女等. 
      

  8.   

    解析顺序对我们来说没什么意义,执行顺序才应该是我们应该关注的。就像你写程序一样,语法检查从左到右还是从右到左没有任何的参考价值。
    对于rbo来说,一般建议把过滤量大的语句写在后面,但10g后已经自动进行cbo统计了,不用过多考虑条件的放置顺序了
      

  9.   

    我想10g的优化器 会帮你搞定这些位置的吧。。
    cbo模式下?
      

  10.   

    这个与解释器的规则有关,比如基于成本规则的,where 后面的条件是从下往上执行,也就是最后的先执行。
      

  11.   

    可以明确的告诉你,SQl语句是从右往左执行的,如果有子查询,也会先做子查询,所以为了提高查询效率,尽量把精确条件往后写,我们做的项目表数据有的数据量达到10几亿,还有点建议,就是尽量不要用*,因为它会调用数据字典,增加查询成本。
      

  12.   

    10g R2貌似没有RBO了.
    感觉应该根据自己对表数据的理解,加ordered提示
      

  13.   

    楼上的好多人好像是在说ORACLE 检查SQL文的语法错误是从哪里开始读。。
    客户端发sql文到ORACLE数据库的时候
    是按以下步骤来执行的
    1。检查sql语法错误(包括字段之类的存在性)。
    2。解析(分为两种 SOFT PARSE和HARD PARSE),如果先前已经有同样的sql文执行过了的话会采用先前的执行计划。如果是第一次执行的sql,会根据统计情报和index等结构来建立最佳的执行计划。这时候ORACLE会根据整个WHERE条件来判断最佳的执行计划。
    3。根据第二步的解析结果去找相应的数据块,作最后的数据更改处理。
      

  14.   

    Oracle优化器会根据最优的执行计划自动调整执行顺序
      

  15.   

    建表;
    create table t_testcolstart as select * from dba_objects; 
    插入数据:
    insert into t_testcolstart select * from t_testcolstart;
    commit;
    insert into t_testcolstart select * from t_testcolstart;
    commit;
    insert into t_testcolstart select * from t_testcolstart;
    commit;
    insert into t_testcolstart select * from t_testcolstart;
    commit;
    insert into t_testcolstart select * from t_testcolstart;
    commit;
    insert into t_testcolstart select * from t_testcolstart;
    commit;
    SQL> select count(*) from t_testcolstart;  COUNT(*)
    ----------
        807088
        
        
    --目前表中以及包含近百万数据--构造条件,测试数据数据一: 
    SQL> select * from t_testcolstart a where a.owner = 'HAHA' and a.object_name = 'HAHA';
    已用时间:  00: 00: 00.06
    SQL> select * from t_testcolstart a where a.object_name = 'HAHA'  and a.owner = 'HAHA';已用时间:  00: 00: 00.07
    SQL> select * from t_testcolstart a where a.owner = 'HAHA';
    已用时间:  00: 00: 00.06
    SQL> select * from t_testcolstart a where a.object_name = 'HAHA';
    已用时间:  00: 00: 00.06几乎看不出什么差距测试二:
    SQL> select * from t_testcolstart a where a.owner = 'HAHA'  and instr(a.object_name,'123') = 1;   b1
    已用时间:  00: 00: 00.07
    SQL> select * from t_testcolstart a where instr(a.object_name,'123') = 1   and a.owner = 'HAHA'; b2
    已用时间:  00: 00: 00.06SQL> select * from t_testcolstart a where instr(a.object_name,'123') = 1;                     b3
    已用时间:  00: 00: 00.31从本组数据我们可以看到 b1 与b2在查询的时候 都忽略了 instr(a.object_name,'123'), 不管其位与什么地方,都是先执行的 owner条件,
    也就可以推出 oracle默认是先比较 干净的字段,后比较带函数的字段,并且实行了短路原则,只要第一个比较结果为否,后续都不会比较
    测试三 SQL> select * from t_testcolstart a where substr(a.object_type,2,4) = 'HAHA'  and instr(a.owner,'123') = 1; c1
    已用时间:  00: 00: 00.29
    SQL> select * from t_testcolstart a where instr(a.owner,'123') = 1   and substr(a.object_type,2,4) = 'HAHA'; c2
    已用时间:  00: 00: 00.24
    SQL> select * from t_testcolstart a where instr(a.owner,'123') = 1 ; c3
    已用时间:  00: 00: 00.23
    SQL> select * from t_testcolstart a where substr(a.object_type,2,4) = 'HAHA'; c4
     已用时间:  00: 00: 00.29从本组数据 我们可以看到 c1与c4相差不多, c2与c3相差不多,也就可以推出 where 执行的过程是从左到右测试四 为了验证结论三 ,再测试一组数据
    SQL> select * from t_testcolstart a where substr(a.owner,2,4) = 'HAHA'  and instr(a.object_type,'123') = 1; d1已用时间:  00: 00: 00.29
    SQL> select * from t_testcolstart a where instr(a.object_type,'123') = 1   and substr(a.owner,2,4) = 'HAHA'; d2已用时间:  00: 00: 00.23
    SQL> select * from t_testcolstart a where instr(a.object_type,'123') = 1 ; d3已用时间:  00: 00: 00.23
    SQL> select * from t_testcolstart a where substr(a.owner,2,4) = 'HAHA'; d4已用时间:  00: 00: 00.30明显可以看出where执行条件是从左到右,并且可以看出instr 的效率要比substr好一点
        
      

  16.   

    顺便说下,我做的测试环境为 oracle10g
      

  17.   

    oracle 10g以后的版本就不要考虑where条件的执行顺序了,毫无意义,你当优化器是傻的啊,连按什么顺序执行最快都不知道.
    37L的钻研精神值得肯定,不过你这个测试第一样本量不足,第二方法也有问题,CBO的具体工作过程我不清楚,但是对于where条件,一定是优先选择执行扫描成本低,返回记录少的条件,比如where条件如果能使用到分区或者索引,那么不管你把相应的where条件写在前面还是后面,它都会首先执行.
      

  18.   


    你以为优化器是万能的?请你告诉我 在比较 a = 5 与 b= 6 这个过程中 哪个成本最低?
    CBO在计算成本的时候大多考虑的是I/O方面的,cpu方面的就比较少就lz的提问而言,我们假设的条件是a.b.c.d这四个条件都是一样的,都不会走索引,也就是在进行全表扫描的情况下而比较的,I/O成本已不再考虑范围内。讨论这个最主要的作用在于使用短路原则,减少CPU进行比较的次数,其并不会减少I/O的产生,当然在大多数情况下,根据大数吃小数的原则,cpu的计算成本相比较I/O是微乎其微的.
    另外我的测试虽然样本不足,但就选定的样本而言也是经过多次测试(不下于40次)的比较才得到的结果,至少可以可以看出oracle在这个样本方面所选用的算法
      

  19.   


    好吧,你自己都说了,优化器都不知道a=5和b=6应该先执行哪个,那你凭什么知道呢?
    在a=1 and b=2 and c=3 这种绝对平衡的where条件中(所谓绝对平衡是指数据分布,返回结果,执行方式等效率全部一样),CBO怎么执行的,有必要去考虑吗,怎么执行的结果都一样。如果where条件不平衡,同样不用考虑先后顺序,因为CBO会把所有where条件平等看待,无所谓先后。
      

  20.   

    orcale 是倒序解析执行的。