为理解如下驱动表的知识,【做如下测试】:A表:
B表:select * from A,B;  0.01 秒 --> 慢
select * from B,A;  0.00 秒 --> 快感觉结果是一样的,只不过调整了下列的顺序。貌似oracle执行前,都先判断了A是小表,2条sql都选了A作为驱动表,
用NL连接方式,即A做外循环,B做内循环,得到以上结果。
问题1:select * from A,B;  -- > 到底oracle把哪个表做驱动表了呢,A? B? 看运行时间慢像B,但是看结果集像A.
问题2:oracle会不会自动判断、调正行数较小的表,优先做驱动表呢?(即使它被放在了倒数第二个位置上)谢谢!

解决方案 »

  1.   

    有没有简单点的办法,确定select * from A,B; 的驱动表??
      

  2.   

    你这样测试逻辑是不严密的,
    每次测试完   要刷新一下缓存 ,alter system flush shared_pool ; 
    保证下次的测试没用到上次的结果集。
    一般来说,oracle的执行顺序是从右到左,小表放在右边会好些,
    不过oracle的优化器是个很复杂的东西,许多底层的东西它会自己判断的。
      

  3.   

    对于CBO,如果没有统计数据,oracle从左往右选择驱动表,如果有统计数据,oracle自动选择驱动表。
    只有在RBO情况下,oracle才从右往左选择驱动表
      

  4.   

    通常情况下,优化器在选择执行计划时,不会考虑表在FROM语句中出现的顺序。优化器依次根据下面的规则来作出选择. 优化器选择执行计划使得内部表为全表扫描的NESTED LOOPS连接尽可能的少;
    from: http://hb.qq.com/a/20111214/001638.htm
      

  5.   

    NESTED LOOPS连接尽可能的少正解,
    优化器选择并不是一定要小表当驱动表,
    如果大表的结果集小,也能当驱动表的。
      

  6.   

    取决于NESTED LOOP 还是hash join 
    这里所谓的大小不是指表本身,是指符合谓语的结果集
    NESTED LOOP是小表做驱动,好处是如果关联条件在大表中有索引且小表结果集行数很少就只需要做少数几次index scan。适合结果集较小的情况。
    如果是hash是大表做驱动。好处是小表放在内存里,大表的只要做一次table access。而起hash值的匹配要比直接比较快。适合结果集较大的时候。缺点是只能=不能<>