现在我有三张表A、B、C要进行关联查询,A与B通过ab字段关联,B与C通过bc字段关联
A表数据大概2W,B表30W,C表100Wselect * from A, B, C
    where A.ab = B.ab
    and B.bc = C.bc;现在存在这样的问题,在一个数据库环境(Oracle 10g)上,这两个条件关联得很好,先将 A、B进行条件关联,再将结果与C关联,没任何问题,对游标循环大概20秒就完成。但是在另一个环境下(同样是Oracle 10g),这条SQL的执行变成了A跟C先做了一次笛卡尔连接,然后再将结果,按两个关联条件与B进行关联查询,循环一次游标需要1个多小时,性能极差。这跟Oracle什么设置有关?

解决方案 »

  1.   

    可以按你的最初的想法写sql,先将 A、B进行条件关联,再将结果与C关联,人为的去指定这样就ok了
      

  2.   

    select * from C, B, A--记录集小的表写在最后
      where A.ab = B.ab
      and B.bc = C.bc;这样测试一下看看!
      

  3.   

    SELECT * FROM 
    C,
    (
    SELECT * FROM A,B WHERE A.AB=B.AB
    )T
    WHERE T.BC=C.BC;
      

  4.   

    执行计划已经用文字描述了,一个环境下的计划是两次hash join,另一个环境下是把两个无关联条件的表做了次笛卡尔积
    有索引,两个环境的表结构跟数据一模一样
    3L,如何人为指定?
    4L的方法在10g下可能不管用,10g是数据库自动优化顺序。
    5L在T不大的时候,倒是个好方法,我试试
      

  5.   

    CBO不至于蠢到这个地步吧,有链接条件不用,要使用笛卡尔链接,估计是你的统计信息收集不正确,重新收集下表的统计信息,使用如下语句
    begin
    dbms_stats.gather_table_stats(ownname => user,tabname => 'A',cascade => trye);
    ..
    end;实在不行就加提示
    select /*+use_hash(b c a) leading(b) */* from A, B, C
      where A.ab = B.ab
      and B.bc = C.bc;
      

  6.   

    4楼的写法应该可以尝试一下,并且C表的bc字段,与B表的ab字段最好要创建索引。