2017-02-16 5 views
0

Webアプリケーションとしてasp.net mvcを使用し、データベースとしてOracle 12C、接続用にOracle.DataAccess.Client(12.1.0,64ビット版)を使用しています。 Oracle Database、およびasp.net MVCアプリケーションは64ビットマシンでも動作します。Oracleストアドプロシージャは、TOADで高速にC#に遅くなります。

ストアドプロシージャの1つが、出力パラメータとしてカーソルを返します。

TOADまたはSQL Developerで同じストアドプロシージャを実行するのに1秒もかかりませんが、C#で同じストアドプロシージャを実行すると約35秒かかります。戻るに戻る。 TOAD、SQL Developer、asp.net iisサーバーはすべてローカルマシン上にあり、Oracleサーバーは異なるマシン上にあります。

C#では、接続のオープンに要した時間、ストアドプロシージャを呼び出すタイムスタンプの時刻、完了した時刻、戻ってきた時刻、DataSetの変換にかかった時間C#リストに追加します。次の文は、35秒

  OracleDataAdapter loDataAdapter = new OracleDataAdapter(loCommand); 
      LogInfo("fill DataTable");//logs time stamp saying start 
      loDataAdapter.Fill(loDataTable); 
      LogInfo("fill DataTable",false);//logs time stamp saying Done 
      loDataAdapter = null; 

を取ることを私たちが見るすべてのタイミングを観察した後、私たちは、そのような場合はヒキガエルとSQL開発者は、同じ時間を取る必要がある場合には、ネットワークの問題になると考えていたので、ネットワークが問題ではありません。

私たちが試したこと: ODP.NETドライバしかないので、すべてのoracleクライアントを削除して再インストールしました。使用しません。

今、sqlnet.oraまたはtnsファイル接続で構成する必要があるかどうかを確認しようとしていますか?しかし、いずれかを見つけることができませんでした...

をここで完全なコード

公共のDataTable GetDataTable(文字列psStoredProcedure) { たLogInfo(psStoredProcedure)があります。

 //****************************************************************** 
     //Function.........GetDataTable 
     //Description......Gets a data set (with the schema) from stored procedure 
     //Input Param......(1)Stored procedure name 
     //     (2)Boolean to determine if we want to get the schema 
     //Output...........Return DataTable 
     // 
     //****************************************************************** 

     OracleCommand loCommand = new OracleCommand(); 
     OracleConnection loConnection = new OracleConnection(msConnectionString); 
     DataTable loDataTable = new DataTable(); 

     //---Main Execution Block 
     try 
     { 
      if (!(loConnection.State == ConnectionState.Open)) 
      { 
       LogInfo("Open Conn"); 
       loConnection.Open(); 
       LogInfo("Open Conn",false); 
      } 

      //---Define the SelectCommand 
      if (moCommand == null) 
      { 
       loCommand = new OracleCommand(); 
      } 
      else 
      { 
       loCommand = moCommand; 
       moCommand = null; 
      } 

      loCommand.CommandText = psStoredProcedure; 
      loCommand.Connection = loConnection; 
      loCommand.CommandType = CommandType.StoredProcedure; 

      //---Populate the dataset 
      OracleDataAdapter loDataAdapter = new OracleDataAdapter(loCommand); 
      LogInfo("fill DataTable"); 
      loDataAdapter.Fill(loDataTable); 
      LogInfo("fill DataTable",false); 
      loDataAdapter = null; 
     } 
     catch (Exception oExcep) 
     { 
      throw oExcep; 
     } 
     finally 
     { 
      //---Close the connection 
      if (loConnection.State == ConnectionState.Open) 
      { 
       LogInfo("Close"); 
       loConnection.Close(); 
       LogInfo("Close", false); 
      } 

      loCommand = null; 
      loConnection = null; 
     } 
     LogInfo(psStoredProcedure, false); 
     return loDataTable;} 

次のストアドプロシージャには、PL/SQLです:私にとって

CREATE OR REPLACE PROCEDURE REF_LIST_INQ ( 
ivID   IN VARCHAR2 DEFAULT NULL,   
ivAID   IN VARCHAR2 DEFAULT NULL, 
ivDID   IN VARCHAR2 DEFAULT NULL, 
ivSelection  IN VARCHAR2 DEFAULT NULL, 
ivStartDate  IN VARCHAR2 DEFAULT NULL, 
ivEndDate   IN VARCHAR2 DEFAULT NULL,  
ocRefList  OUT ES_PACKAGE.cursorType, 
ovReturnCode  OUT VARCHAR2, 
ovErrorMsg   OUT VARCHAR2 
) 
AS 

cmdSQL  VARCHAR2(4000) := NULL; 
whereCause VARCHAR2(2000) := NULL; 
selectCause VARCHAR2(2000) := NULL; 


BEGIN 
    /************ 
--Hundreds of lines of PL/SQL Code for 
    -- dynamically creating sql statements 
    -- and assigning it to 'selectCause' and 'whereCause' 
*************************/ 

    cmdSQL := selectCause || whereCause || ' ORDER BY SD.MODIFIED_DATE DESC, SD.REFERRAL_NUMBER'; 

    OPEN ocRefList FOR cmdSQL; 
    ovReturnCode := '0'; 

    EXCEPTION WHEN OTHERS THEN 
     ovErrorMsg := 'REF_LIST_INQ - ' || SUBSTR(SQLERRM,1,200); 
     ovReturnCode := '-1'; 

END REF_LIST_INQ; 
/
+0

また、plsqlテストコードをポストしてください - 私はあなたがカーソルを返すだけだと思いますが、そこからすべてのレコードを引き出すわけではありません - これは "Fill"ステートメントの処理です。 –

+0

ストアドプロシージャ内のpl/sqlは動的に作成されたステートメントであり、変数 'c​​mdSQL'に割り当てられます。最後に、そのステートメントのカーソルを開きます。 – venu

+0

次のように、OPEN ocReferralList FOR cmdSQL;すぐに私の質問にpl/sqlを追加します。 – venu

答えて

0

これが答えです誰かがそれを試してみることができます同じような状況に直面している場合であってもよいです。

数日後に調査した結果、C#の次の文が私を助けました。私は信じている(私の理解あたりとして

loCommand.FetchSize = loCommand.FetchSize * 18192; 

は、これが唯一の64ビット版で動作します(私は私のレベル最善をしようとし、記述が得意ではないです)、そして私たちは「のFetchSize」を指定しない場合には、事前に定義されたサイズをフェッチし続けます128k)のデータをOracle DBでオープンした場合、カーソルによって提供されるデータが処理されるまで往復します。

ここでは完全なC#コードですが、1行のコードで大きな違いがありました。

//****************************************************************** 
    //Function.........GetDataTable 
    //Description......Gets a data set (with the schema) from stored procedure 
    //Input Param......(1)Stored procedure name 
    //     (2)Boolean to determine if we want to get the schema 
    //Output...........Return DataTable 
    // 
    //****************************************************************** 

    OracleCommand loCommand = new OracleCommand(); 
    OracleConnection loConnection = new OracleConnection(msConnectionString); 
    DataTable loDataTable = new DataTable(); 

    //---Main Execution Block 
    try 
    { 
     if (!(loConnection.State == ConnectionState.Open)) 
     { 
      LogInfo("Open Conn"); 
      loConnection.Open(); 
      LogInfo("Open Conn",false); 
     } 

     //---Define the SelectCommand 
     if (moCommand == null) 
     { 
      loCommand = new OracleCommand(); 
     } 
     else 
     { 
      loCommand = moCommand; 
      moCommand = null; 
     } 

     loCommand.CommandText = psStoredProcedure; 
     loCommand.Connection = loConnection; 
     loCommand.CommandType = CommandType.StoredProcedure; 
//Here is the Hero 
loCommand.FetchSize = loCommand.FetchSize * 18192; 

     //---Populate the dataset 
     OracleDataAdapter loDataAdapter = new OracleDataAdapter(loCommand); 
     LogInfo("fill DataTable"); 
     loDataAdapter.Fill(loDataTable); 
     LogInfo("fill DataTable",false); 
     loDataAdapter = null; 
    } 
    catch (Exception oExcep) 
    { 
     throw oExcep; 
    } 
    finally 
    { 
     //---Close the connection 
     if (loConnection.State == ConnectionState.Open) 
     { 
      LogInfo("Close"); 
      loConnection.Close(); 
      LogInfo("Close", false); 
     } 

     loCommand = null; 
     loConnection = null; 
    } 
    LogInfo(psStoredProcedure, false); 
    return loDataTable;} 
関連する問題