有2个表t1和t2
create table t1(t1pk varchar(100) ,t1a varchar2(128),t1b varchar2(128),t1c varchar2(36) default('0') ...)
create table t2(t2a varchar2(128),t2b varchar2(128),t2c varchar2(36),t2d date default(sysdate)  ...)
其中t1是主表,t2是从表,但是他们没有外键约束,只是t1a =t2a ,t1b=t2b
现在t1表有记录128行左右,t2有记录30w左右,两个表都没有建索引,
现有如下sql:就是从t2中根据t2a ,t2d分组取得最大的t2d,并自身关联取得最大t2d中的t2b字段,并与主表t1关联查出t1c=‘1’的记录,此sql也不复杂select distict t1.t1b from t1
inner join (select t2a,t2b from t2 a, (
select t2a,max(t2d) d from t2 b
                  where t2a='a'
group by t2a,t2d
        )
         where a.t2a=b.t2a and a.t2d=b.d        
        ) tt
        on t1.t1b=tt.t2b
        and t1.t1a=tt.t2a
    where  t1.t1c='1'
问题如下:
1、如果没有最后的where语句,t1.t1c='1',此脚本可以查出一条记录,并且不用1s就可以查出结果,但是有了where条件,在pl/sql 中执行不出来结果,就好像死锁一样(可以确认不是死锁,没有其他人进行查询或者更新的操作)2、讲inner join改为left join 可以很快查出结果,但是不满足业务要求,改为right join也可以查出,但是相对比较慢,为什么inner join会非常慢?3、将t1同t2处于同一级别关联,改造为
select distict t1.t1b from t1
inner join (select t2a,t2b from t2 a, (
select t2a,max(t2d) d from t2 b
group by t2a,t2d
        )
         where a.t2a=b.t2a and a.t2d=b.d        
        ) tt
        on t1.t1b=tt.t2b
        and t1.t1a=tt.t2a
    where  t1.c='1' --and b.t2a='a'
也是很快得到结果,或者where条件为 where   b.t2a='a'
也是很快可以得到结果 ,但是当where条件为 t1.c='1' and b.t2a='a',sql就会执行很长时间也得不到结果,同样用exists或者in等替代,也是执行很长时间查看过各种执行计划,基本一样,没多大差别,都是使用table scanoracle 使用的10G,
在另外的一个oracle环境中,数据条目等基本一致,执行以上查询,只需用1s左右就可以完成,对比了两个的执行计划,也是一致!!会是什么问题导致??????不得其解,请教高人!!

解决方案 »

  1.   

    两个oracle执行计划一致没有where语句的sql
    select distict t1.t1b from t1
    inner join (select t2a,t2b from t2 a, (
    select t2a,max(t2d) d from t2 b
      where t2a='a'
    group by t2a,t2d
      )
      where a.t2a=b.t2a and a.t2d=b.d   
      ) tt
      on t1.t1b=tt.t2b
      and t1.t1a=tt.t2a
     
    和有where语句的也差别不大,所以就不得其解,不知道为什么