请教各位,这个是什么问题? 太抑郁了
在oracle包中,有一个sql如下:procedure p_1(pi_id in number,  po_return out varchar2)
...     select count(*)
         into v_cnt
        from table1 a        --其中table1 是通过dblink访问的远程数据库对象(建了同义词)
     where id = pi_id;     --id为主键
   
...程序执行到这里时,会锁住。 但是如果单独执行这个sql ,速度正常, 查看执行计划,也用到了索引。同时,如果在过程中,将pi_id 替换为常量值,执行也非常正常。 oracle版本为 9.206请问各位有没有人碰到过这个问题?如何解决?

解决方案 »

  1.   

    表里有没有这个pi_id的字段呀。换个变量名试试。 这里是慢还是锁了,查一查 datalink数据库的session和lock信息。
      

  2.   

    建议使用动态sql,通过绑定变量执行,参考语句:
    execute immediate 'select count(*)  from from table1 a where id = :1' into v_cnt  using pi_id;
      

  3.   


    pi_id 是变量,不是字段.
      

  4.   

    把dblink创建为public:   
      create   public   database   link   .....  
      

  5.   

    pi_id 和id类型一致?
    奇怪,关注下
      

  6.   


    在这个sql语句之前有没有什么地方用到过pi_id或对它进行一些操作?  
    或许是内部逻辑有些问题。
      

  7.   


    pi_id 没有被重新赋值。
    在这个语句的前一条语句,也直接引用到了这个变量。奇怪的是,上一个语句使用到了本地表和远程表,反而能够正常查询,不过需要增加  /*+driving_site(b)*/  暗示。 即整个过程的如下:
    procedure p_1(pi_id in number,  po_return out varchar2) 
    ... 
       
        --查询正常
        SELECT /*+driving_site(b)*/ COUNT(1) 
          INTO v_count
        FROM local_table a,remote_table b  --  local_table为本地库表 ,remote_table为远程表
        WHERE a.id=b.id
          AND b.type='55'
          AND b.state='1'
          AND a.id=pi_id;     IF v_count>=1 THEN
           RETURN;
         END IF;    --查询死锁 
        select count(*) 
            into v_cnt 
            from table1 a        --其中table1 是通过dblink访问的远程数据库对象(建了同义词) 
        where id = pi_id;    --id为主键 
      
    ... 真是莫名奇妙啊
      

  8.   

    fzymr: pi_id 是变量,不是字段.虽然pi_id 是变量,不是字段,但是如果表里有字段叫pi_id那么执行的时候也可能出问题,最好修改下试试,如用v_pi_id。
      

  9.   

    虽然pi_id 是变量,不是字段,但是如果表里有字段叫pi_id那么执行的时候也可能出问题,最好修改下试试,如用v_pi_id。
      

  10.   

    加上一个HINT就可以,/*+ driving_site(a) */
        select /*+ driving_site(a) */ count(*)
            into v_cnt
            from table1 a        --其中table1 是通过dblink访问的远程数据库对象(建了同义词)
        where id = pi_id;    --id为主键 
      

  11.   

    procedure是预编译的,select .....where id= XX 在id的值不确定时,编译出来的plan不会走索引。所以建议你改为动态SQL,用EXCUTE ...
      

  12.   

    这里的问题在于两方面*. 当使用常量,比如b.type='55'和使用变量作为条件查询时,Oracle的执行计划可能不同。在使用常量的情况下,Oracle根据STATS能精确地计算出COST,但是用变量是,就只能估计了。
    *. 在使用DBLINK的时候,如果在另一个库的表纪录很多的话而加上条件以后纪录集很小的话,就应该加上driving_site HINT。加上这个HINT的作用是让另一个库执行条件判断然后返回纪录,不加的话所有在异库的纪录都会先传到本地然后进行条件判断。其性能区别是非常明显的。
      

  13.   

    查了下等待事件,结果如下: Select * From v$session_wait Where sid = 21; 
    event为 SQL*Net break/reset to dblink把这个存储过程另存为一个过程名,然后执行发现又ok了,要抓狂了。
      

  14.   

    SQL*Net break/reset to dblink 倒是第一次碰到,搜索网上的资料,好像在特定的Oracle version中有这个问题。你的数据库是什么版本的?详细参见:http://dbaspot.com/forums/oracle-server/86660-problem-insert-into-remote-table-dblink-hangs-after-migration-8-0-6-9-2-0-a.html