现有oracle 11g r2 安装在A服务器和B服务器上,分别为 A数据库和B数据库。
且A、B 数据库 都有表 ctltmp.wrs_dhhm1(1万数据量)、ctltmp.tb_ms_trading_stamps(22万数据量)。-- 在A数据库执行下面sql,要180多秒才能出结果
SELECT t2.*
  From ctltmp.wrs_dhhm1 t1, ctltmp.tb_ms_trading_stamps@B t2
 WHERE t1.bm = t2.stamps_code;
-- 执行计划如下:-- 在B数据库执行同样的sql,2秒就能出结果
SELECT t2.*
  From ctltmp.wrs_dhhm1 t1, ctltmp.tb_ms_trading_stamps@A t2
 WHERE t1.bm = t2.stamps_code;
-- 执行计划如下:
为什么两台数据库之间A通过dblink关联B的表这么慢,而B通过dblink关联A这么快呢?执行计划是一样的。
如果是网络的问题的话,两个不是应该都慢的吗?
-- 再做一个测试如下,在A服务器上加hint,执行sql,2秒就出结果
SELECT /*+driving_site(t2)*/t2.*
  From ctltmp.wrs_dhhm1 t1, ctltmp.tb_ms_trading_stamps@B t2
 WHERE t1.bm = t2.stamps_code;
-- 执行计划如下:
问题:为什么oracle不默认选择这种速度较快的查询计划呢?这个问题困扰我很久了,问了很多人,发了很多帖都没解决,麻烦各位大神牛人帮忙看看,走过路过的帮忙顶下!
谢谢!

解决方案 »

  1.   

    建议做一下SQL TRACE,看看SQL语句的执行情况,是否有等待事件
      

  2.   

    -- vanjayhsu 所言及是,结果如下。大部分等待事件是 dblink,这意味着什么呢?
    SELECT b.*
      From ctltmp.wrs_dhhm1 a, ctltmp.tb_ms_trading_stamps@B b
     WHERE a.bm = b.stamps_codecall     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.00       0.02          0          0          0           0
    Execute      1      0.00       0.00          0          0          0           0
    Fetch        1      2.07     165.38          0         37          0         100
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        3      2.07     165.41          0         37          0         100Misses in library cache during parse: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 87  Rows     Row Source Operation
    -------  ---------------------------------------------------
        100  HASH JOIN  (cr=37 pr=0 pw=0 time=12147993 us cost=925 size=6806015 card=18545)
      10000   TABLE ACCESS FULL WRS_DHHM1 (cr=37 pr=0 pw=0 time=1898 us cost=12 size=190000 card=10000)
      26951   REMOTE  TB_MS_TRADING_STAMPS (cr=0 pr=0 pw=0 time=2351164 us cost=910 size=145477572 card=418039)
    Elapsed times include waiting on following events:
      Event waited on                             Times   Max. Wait  Total Waited
      ----------------------------------------   Waited  ----------  ------------
      SQL*Net message to client                       2        0.00          0.00
      SQL*Net message from client                     2        0.02          0.04
      SQL*Net message to dblink                   13476        0.00          0.01
      SQL*Net message from dblink                 13476        0.02        163.67
      SQL*Net more data to client                     1        0.00          0.00
      

  3.   

    tb_ms_trading_stamps表比wrs_dhhm1表的数据量大,通过DBLINK传输的时间也相应多些。
    如果stamps_code的选择性较好,可以建索引试试看。
      

  4.   

    明显就是从A访问B很慢,
    你试试看,只是
    A站:select * from ctltmp.tb_ms_trading_stamps@B;
    B站:select * from ctltmp.tb_ms_trading_stamps@A;
    比较下结果?
      

  5.   


    Rows Row Source Operation
    ------- ---------------------------------------------------
      100 HASH JOIN (cr=37 pr=0 pw=0 time=12147993 us cost=925 size=6806015 card=18545)
      10000 TABLE ACCESS FULL WRS_DHHM1 (cr=37 pr=0 pw=0 time=1898 us cost=12 size=190000 card=10000)
      26951 REMOTE TB_MS_TRADING_STAMPS (cr=0 pr=0 pw=0 time=2351164 us cost=910 size=145477572 card=418039)--我认为是这个评估有问题Rows Row Source Operation
    26951 REMOTE TB_MS_TRADING_STAMPS (cr=0 pr=0 pw=0 time=2351164 us cost=910 size=145477572 card=418039)
    --明显TB_MS_TRADING_STAMPS只有22万数据量,但是card=418039,导致DBLINK读取的数据多了一倍,因此性能变差了,这个是CBO的问题,感觉好像是没有获取到正确的统计信息
      

  6.   

    根据你的回答。我再做了一次测试。
    A库:select * from ctltmp.tb_ms_trading_stamps@B where rownum<=50;
    B库:select * from ctltmp.tb_ms_trading_stamps@A where rownum<=50;
    这样两条执行时间基本都稳定 0.2秒-0.3秒。
    加了rownum 是不是意味着 oracle不会去读统计信息,直接返回前50条数据,所以查询就变稳定了呢?
      

  7.   

    消耗在网络传输的时间,默认是t1作为驱动表,所以t2要通过dblink传输到t1的数据库,driving_site修改了传输顺序,t1的数据量比t2要小的多,所以快