2012-09-13 4 views
6

데이터로드 성능을 향상시켜야합니다. 현재 algorythm 테이블에서 전체를 선택합니다 :데이터 삽입/업데이트 성능을 향상시키는 방법은 무엇입니까?

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

새로운 데이터는 텍스트 파일에서 읽기 (예를 들어, 데이터 테이블 행 당 TEXTFILE 라인). 테이블에 기본 키가 있으며 두 개의 필드가 있습니다. 텍스트 파일의 각 행에 대해이 두 필드 (즉 기본 키)를 사용하여 필요한 행을 찾습니다.

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

Locate하면 반환 True, 그것은 그렇지 않으면 새로운 하나를 추가, 행을 편집합니다.

테이블이 약 200000 개의 행으로 구성되어있는 한 각각의 Locate 작업에는 일정 시간이 걸리므로 초당 약 5-6 개의 행을 업데이트 관리합니다.

개선을 위해 고려해야 할 사항은 무엇입니까?

아마도이 위대한 선택을 통해 별도의 쿼리로 대체 할 것입니까?

답변

10

Locate()를 사용하지 마십시오. locate()를 사용하면 델파이는 쿼리에서 행 집합을 검색하는 클라이언트 측에서 행을 검색하는데 많은 시간이 걸립니다.

저장 프로 시저를 만들려면 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 [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로이 저장 프로 시저를 호출하는 델파이 코드 :

...... 
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 버전 인 경우 두 개의 SQL 명령 UPDATE 및 INSERT를 사용할 수 있습니다. 그리고 데이터 소스는 (1) OPENROWSET 또는 (2) DB 테이블을 사용하십시오.
+0

내 상황에 valex하여 대답을 적용하기가 훨씬 쉬웠지만, 도움을 주셔서 감사합니다. 대상 SQL Server는 2000입니다. 꽤 오래된 것입니다. 일부 임시 테이블 (및 기타 ..)에 파일을로드하기 위해 전체 algorythm을 리메이크하는 것은 valex가 제공 한 아이디어 덕분에 내가 얻은 것과 비교했을 때 어떤 성능 향상도 가치가 없다. . 어쨌든 감사합니다! – horgh

관련 문제