2012-09-13 12 views
6

データロードのパフォーマンスを向上させる必要があります。現在algorythmがテーブルから全選択可能:データの挿入/更新のパフォーマンスを向上させる方法は?

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

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

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

Locateであれば戻りTrue、それはそうでなければ、それは新しいものが追加され、行を編集します。

したがって、表が約200000行からなる限り、各操作は一定の時間がかかります...したがって、1秒あたり約5-6行の更新を管理します。

改善のためにどのようなことを考慮する必要がありますか?

おそらく、この素晴らしい選択肢を別のクエリで置き換えてください。

答えて

10

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

ストアドプロシージャを作成するためにMSSQLにアクセスできる場合は、以下の手順を作成し、条件なしでTEXTファイルの各行に対して実行します(DelphiでTAdoStoredProc.ExecProcを使用します)。したがって、この場合は、最初にSelectおよびLocateプロシージャを実行する必要はありません。 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 [email protected],[email protected] 
     where [email protected] and [email protected]; 
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; 
+3

この溶液は、ローディング時間を4時間から4分未満に短縮しました。私は本当にあなたの助けに感謝します!ありがとうございました! – horgh

5
  1. 可能であれば、テキストファイルをSQL Serverを実行するサーバーに送信する必要があります。その後、OPENROWSET(BULK)を使用してテキストファイルを開きます(「E.テキストファイルから行を取り出すためのフォーマットファイルでのOPENROWSET BULKプロバイダの使用」を参照)。
  2. テキスト・ファイルをサーバーに送信できない場合は、一時的または永続的なDB表を作成し、INSERTを使用してすべてのテキスト・ファイル行を表に挿入します。
  3. SQL Server 2008を使用している場合は、MERGE演算子を使用する必要があります。より古いSQL Serverのバージョンの場合は、UPDATEとINSERTという2つのSQLコマンドを使用できます。データソースとして、(1)OPENROWSETまたは(2)DBテーブルを使用します。
+0

それは私の状況にvalexで答えを適用する方がはるかに簡単でしたが、助けてくれてありがとう。ターゲットのSQL Serverは2000年でもあります。かなり古いものです。私が達成したもの(と私がそれに費やした時間)と比較して、ある種の一時的なテーブル(と.. ..)にファイルを読み込む全体のalgorythmを改造することは、valexによって与えられた考えのおかげで、 。とりあえずありがとう! – horgh

関連する問題