DB는 오라클 9i 입니다. 클라이언트도 9i입니다.
프로그램은 Delphi 7/Kylix3에서 사용하고 기본 코딩은 delphi7에서 합니다.
원래 프로그램은 아래에 있는 주석 부분으로 처리하였는데 잘 되더군요.
다만 시간이 너무 걸리는 관계로...
약 500건 전후의 행을 저장하는데 2분정도 걸립니다.
쿼리가 저장할 때마다 바뀌어 그런가하고 동일 쿼리에 파라미터를 변경하는 형태로 바꾸었습니다.(쿼리 재사용을 위해서...)
그랬더니 실행할 때 오류가 발생합니다. dbexpress error: Invalid Field type
왜 그럴까요? 이리저리 테스트를 해보았지만 일주일째 헤매고 있습니다.
굳이 이 형태가 아니어도 속도를 개선할 방법을 알수 있을까요?
윈도와 리눅스에서 동시에 작동하여야 합니다.
// 해당 Layer의 셀 정보를 DB에 저장
// 입력 => LL : layer, Cel : 셀 수, Wei : 셀당 필드의 수.
// DB => mazacell (id, layer, cell, /* 이상 number(12) */
w00, w01, w02, ..., w45) /* float */
// primary key (id, layer, cell)
// 전역변수 Col[] : 칼럼 이름을 저장한 스트링 배열
// 전역변수 FLife[i].Dna[,,] : 저장될 float형 자료를 가진 배열
// 전역변수 TempStr : 임시로 사용하는 문자열.
// 전역변수 Qry2 : TSqlQuery instance. SQLConnection에 연결되었음.
procedure LayerUpdate(LL, Cel, Wei : integer);
var
j, k : integer;
begin
// for j := 0 to Cel -1 do begin
// // update 쿼리문자열 구성. w00=0.12317 형태로.
// TempStr2 := format('%s=%g',[Col[0], FLife[i].Dna[LL,j,0]]);
// for k := 1 to Wei -1 do
// TempStr2 := TempStr2 + format(',%s=%g',[Col[k], FLife[i].Dna[LL,j,k]]);
// Qry2.SQl.Clear;
// Qry2.SQL.Add('update mazacell set '
// + TempStr2
// + ' where '
// + 'id = ' + IntToStr(FLife[i].id) + ' and '
// + 'layer = ' + IntToStr(LL) + ' and '
// + 'cell = ' + IntToStr(j));
// Qry2.ExecSQL(true);
// end;
//------- test for speed up.
// update 쿼리문자열 구성. w00=:w00 형태로.
TempStr2 := Col[0] + '=:' + Col[0];
for k := 1 to Wei -1 do
TempStr2 := TempStr2 + ',' + Col[k] + '=:' + Col[k];
Qry2.Sql.Clear;
Qry2.Params.Clear;
Qry2.Sql.Add('update mazacell set ' + TempStr2
+ ' where id=:id and layer=:layer and cell=:cell');
// 파라미터 생성
for k := 0 to Wei -1 do
Qry2.Params.CreateParam(ftFloat, Col[k], ptInput);
Qry2.Params.CreateParam(ftInteger, 'ID', ptInput);
Qry2.Params.CreateParam(ftInteger, 'Layer', ptInput);
Qry2.Params.CreateParam(ftinteger, 'Cell', ptInput);
// 각 cell 별로 파라미터를 저장하고 쿼리 실행.
for j := 0 to cel -1 do begin
for k := 0 to Wei -1 do
Qry2.Params[k].AsFloat := FLife[i].Dna[LL,j,k];
Qry2.Params[Wei].AsInteger := FLife[i].id;
Qry2.Params[Wei +1].AsInteger := LL;
Qry2.Params[Wei +2].AsInteger := j;
Qry2.ExecSQL(false);
end;
//------- test end.
end;
파라미터 타입을 다른 형태로 바꾸어서 적용 시켰습니다.
float - float => BCD - currency
integer - integer => string - string
http://podgoretsky.com/ftp/Docs/DB/QGDBE/quickguide_dbexpress.htm
에서 참조 했습니다.
약 20초 정도 개선 효과가 있네요. 기대한 만큼은 못미치지만...
좀 더 나은 방법이 있으면 알려주세요. 시험용 자료는 500건 정도이지만
실제 적용할 자료는 50만건 정도인지라...
...<전략>
Qry2.Params.Clear;
Qry2.Sql.Add('update mazacell set ' + TempStr2
+ ' where id=:id and layer=:layer and cell=:cell');
// 파라미터를 생성하면 실제 파라미터의 수가 2배가 되었음.
// 아마 params.clean의 위치와 관련이 있지 않을까 추정. test 않음.
// // 파라미터 생성
// for k := 0 to Wei -1 do
// Qry2.Params.CreateParam(ftBCD, Col[k], ptInput);
// Qry2.Params.CreateParam(ftString, 'ID', ptInput);
// Qry2.Params.CreateParam(ftString, 'Layer', ptInput);
// Qry2.Params.CreateParam(ftString, 'Cell', ptInput);
for j := 0 to cel -1 do begin
for k := 0 to Wei -1 do
// Qry2.Params[k].AsFloat := FLife[i].Dna[LL,j,k];
Qry2.Params[k].AsBCD := StrToCurr(VarToStr(FLife[i].Dna[LL,j,k]));
// Qry2.Params[Wei].AsInteger := FLife[i].id;
// Qry2.Params[Wei +1].AsInteger := LL;
// Qry2.Params[Wei +2].AsInteger := j;
Qry2.Params[Wei].AsString := IntToStr(FLife[i].id);
Qry2.Params[Wei +1].AsString := IntToStr(LL);
Qry2.Params[Wei +2].AsString := IntToStr(j);
Qry2.ExecSQL(false);
end;