看一看执行计划.
set autotrace traceonly;
执行SQL

解决方案 »

  1.   

    ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并. 
    例如: 
    表 TAB1 16,384 条记录 
    表 TAB2 1 条记录 
    选择TAB2作为基础表 (最好的方法) 
    select count(*) from tab1,tab2 执行时间0.96秒 
    选择TAB2作为基础表 (不佳的方法) 
    select count(*) from tab2,tab1 执行时间26.09秒 
    如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表. 
      

  2.   

    where 
    b.mt like '%mt%' and 
    a.ms=b.mn and 
    a.rsi = c.rsi and 
    c.rsi ='20000000' and
    a.ind > to_date('20041208','yyyymmdd')
    where 
    b.mt like '%mt%' and 
    a.ms=b.mn and 
    a.rsi ='20000000' and
    a.ind > to_date('20041208','yyyymmdd')比较这两个条件:条件语句从后向前,a.ind > to_date('20041208','yyyymmdd'),相同,c.rsi ='20000000' 和a.rsi ='20000000' 应该相差无几,(因为ta和tc都是几十万条的记录,tc是几十条记录),关键在这句a.ms=b.mn 和a.ms=b.mn and a.rsi = c.rsi ,后者是使用前一个记录集c.rsi ='20000000'和a中匹配出记录集,满足条件的a的子集就小很多了,而前者则是拿出a.rsi ='20000000'的子集直接去匹配a.ms=b.mn ,得到楼主的结果也没有什么奇怪的。
      

  3.   

    感谢大家的提示不过这个还是有点不理解:a.ms=b.mn and a.rsi ='20000000'和a.ms=b.mn and a.rsi = c.rsi and c.rsi ='20000000' a.ms=b.mn and a.rsi = c.rsi and c.rsi ='20000000' 这一句翻译过来,
    好像应该就是a.ms=b.mn and a.rsi ='20000000',并没有因为试用了转意而是查询的结果集变小是么?