6

データ読み込みのパフォーマンスを改善する必要があります。現在のアルゴリズムは、テーブルから完全に選択します。

select Field1, Field2,...,FieldN from Table1 order by FieldM

新しいデータはテキストファイルから読み取られます(たとえば、データテーブル行ごとのテキストファイル行)。テーブルには、2つのフィールドを含む主キーがあります。テキストファイルの各行について、これら2つのフィールド(つまり主キー)によって必要な行を検索します。

query.Locate('Field1;Field2',VarArrayOf([Value1,Value2]),[]);

Locateを返す場合はTrue行を編集し、そうでない場合は新しい行を追加します。

したがって、テーブルが約200000行で構成されている限り、各Locate操作には一定の時間がかかります...したがって、1秒あたり約5〜6行を更新することができます。

それを改善するために私は何を考慮すべきですか?

おそらく、この優れた選択を介した検索を個別のクエリに置き換えますか?

4

2 に答える 2

10

Locate()を使用しないでください。Locate()を使用する場合、Delphiはクライアント側で行を検索し、クエリから行セットをスキャンするだけで、かなりの時間がかかります。

MSSQLにアクセスしてストアドプロシージャを作成できる場合は、次のプロシージャを作成し、条件なしでTEXTファイルの各行に対して実行します(DelphiではTAdoStoredProc.ExecProcを使用します)。したがって、この場合、最初に選択して検索する手順は必要ありません。Filed1とField2が見つかった場合はレコードを更新し、見つからなかった場合は挿入します。

CREATE PROCEDURE dbo.update_table1 
@Field1 int, --key1
@Field2 int, --key2
@Field3 int, -- data fileds
@Field4 int

AS

SET NOCOUNT ON
update table1 set Field3=@Field3,Field4=@Field4 
        where Field1=@Field1 and Field2=@Field2;
IF(@@Rowcount=0)
BEGIN
     insert into table1(Field1,Field2,Field3,Field4) 
                values (@Field1,@Field2,@Field3,@Field4);
END
GO

ADOでこのストアドプロシージャを呼び出すためのDelphiコードは次のとおりです。

......
var 
     ADOStoredP: TADOStoredProc;

  ......
begin

........
    ADOStoredP:=TADOStoredProc.Create(nil);
   try
      ADOStoredP.Connection:=DataMod.SQL_ADOConnection; //Your ADO Connection instance here
      ADOStoredP.ProcedureName:='Update_table1';
      ADOStoredP.Parameters.CreateParameter('@Field1', ftInteger, pdInput, 0, 0);
      ADOStoredP.Parameters.CreateParameter('@Field2', ftInteger, pdInput, 0, 0);
      ADOStoredP.Parameters.CreateParameter('@Field3', ftInteger, pdInput, 0, 0);
      ADOStoredP.Parameters.CreateParameter('@Field4', ftInteger, pdInput, 0, 0);

      While () -- Your text file loop here
      begin

      ADOStoredP.Parameters.ParamByName('@Field1').Value:=Field1 value from text file here;
      ADOStoredP.Parameters.ParamByName('@Field2').Value:=Field2 value from text file here;
      ADOStoredP.Parameters.ParamByName('@Field3').Value:=Field3 value from text file here;
      ADOStoredP.Parameters.ParamByName('@Field4').Value:=Field4 value from text file here;

      ADOStoredP.ExecProc;

      end

    finally
      if Assigned(ADOStoredP) then
        begin
         ADOStoredP.Free;
        end;
    end;

........
end;
于 2012-09-13T05:57:09.177 に答える
5
  1. 可能であれば、SQLServerを実行しているサーバーにテキストファイルを送信する必要があります。次に、OPENROWSET(BULK)を使用してテキストファイルを開きます(「E.フォーマットファイルでOPENROWSET BULKプロバイダーを使用してテキストファイルから行を取得する」を参照)。
  2. テキストファイルをサーバーに送信できない場合は、一時または永続のDBテーブルを作成し、INSERTを使用してすべてのテキストファイルの行をテーブルに挿入します。
  3. SQL Server 2008を使用している場合は、MERGE演算子を使用する必要があります。古いバージョンのSQLServerの場合は、UPDATEとINSERTの2つのSQLコマンドを使用できます。また、データソースとして(1)OPENROWSETまたは(2)DBテーブルを使用します。
于 2012-09-13T05:04:07.457 に答える