特
特尔斐
Unregistered / Unconfirmed
GUEST, unregistred user!
系统架构:
GUI客户端/COM+应用服务器/MS SQL SERVER2000数据库
问题起因:
当客户端需要从服务器取得大数据集到本地时(比如离线业务),通过TDataSetProvider返回这种数据集会使用系统慢如蜗牛。如果直接将ADO数据集返回到客户端将会快许多倍!
目前解决办法:
通过ADO返回结果集。(附测试代码及数据)
存在问题:
1、如何将ADO数据集不通过文件中转而直接存入流?
2、有没有更好的提高MIDAS处理大数据集的方法?
(不要说分段读取,有时需要一次性返回整个数据集)
终极解决方案:
还望各位大侠广施援手!
具体测试数据如下:
用ADO通过文件中转返回TADODataSet记录集
记录数:7268(64个字段)
平均耗时:2466ms
用MIDAS返回TClientDataSet记录集
记录数:同上
平均耗时:8545ms
结论:用ADO的速度是MIDAS的3.46倍
且随着记录数增加,其差距还在扩大
(如果ADO不通过文件中转应会更快)
测试代码如下(下面两个过程是应用服务器上的):
{用ADO通过文件返回记录集}
function TChainGSPRDM.GetDataSet(iClientID: Integer;
const SQLText: WideString): OleVariant;
var
adsObj: TADODataSet;
sFile: string;
M: TMemoryStream;
function TempFileName: string;
var
p: array[0..MAX_PATH - 1] of char;
begin
GetTempPath(MAX_PATH, p);
Result := p + IntToStr(GetTickCount) + '.~tmp';
end;
begin
Result := Null;
InitByClient(iClientID);
adsObj := TADODataSet.Create(nil);
M := TMemoryStream.Create;
try
adsObj.Connection := adoConn;
adsObj.CommandText := SQLText;
adsObj.Open;
if adsObj.IsEmpty then
Exit;
sFile := TempFileName;
adsObj.SaveToFile(sFile);
//使用文件中转,牺牲了一些效率
adsObj.Close;
M.LoadFromFile(sFile);
StreamToVariant(M, Result);
DeleteFile(sFile);
finally
SetAbort;
adsObj.Free;
M.Free;
end;
end;
{通过MIDAS返回记录集}
function TChainGSPRDM.GetDataSetEx(iClientID: Integer;
const SQLText: WideString): OleVariant;
var
adsObj: TADODataSet;
dspObj: TDataSetProvider;
begin
Result := Null;
InitByClient(iClientID);
adsObj := TADODataSet.Create(nil);
dspObj := TDataSetProvider.Create(nil);
try
adsObj.Connection := adoConn;
adsObj.CommandText := SQLText;
dspObj.DataSet := adsObj;
adsObj.Open;
if adsObj.IsEmpty then
Exit;
Result := dspObj.Data;
//从ADO数据集到DataSetProvider.Data的转换最耗时间
adsObj.Close;
finally
SetAbort;
adsObj.Free;
dspObj.Free;
end;
end;
哪位大侠帮忙解决这个问题,300分奉上!
GUI客户端/COM+应用服务器/MS SQL SERVER2000数据库
问题起因:
当客户端需要从服务器取得大数据集到本地时(比如离线业务),通过TDataSetProvider返回这种数据集会使用系统慢如蜗牛。如果直接将ADO数据集返回到客户端将会快许多倍!
目前解决办法:
通过ADO返回结果集。(附测试代码及数据)
存在问题:
1、如何将ADO数据集不通过文件中转而直接存入流?
2、有没有更好的提高MIDAS处理大数据集的方法?
(不要说分段读取,有时需要一次性返回整个数据集)
终极解决方案:
还望各位大侠广施援手!
具体测试数据如下:
用ADO通过文件中转返回TADODataSet记录集
记录数:7268(64个字段)
平均耗时:2466ms
用MIDAS返回TClientDataSet记录集
记录数:同上
平均耗时:8545ms
结论:用ADO的速度是MIDAS的3.46倍
且随着记录数增加,其差距还在扩大
(如果ADO不通过文件中转应会更快)
测试代码如下(下面两个过程是应用服务器上的):
{用ADO通过文件返回记录集}
function TChainGSPRDM.GetDataSet(iClientID: Integer;
const SQLText: WideString): OleVariant;
var
adsObj: TADODataSet;
sFile: string;
M: TMemoryStream;
function TempFileName: string;
var
p: array[0..MAX_PATH - 1] of char;
begin
GetTempPath(MAX_PATH, p);
Result := p + IntToStr(GetTickCount) + '.~tmp';
end;
begin
Result := Null;
InitByClient(iClientID);
adsObj := TADODataSet.Create(nil);
M := TMemoryStream.Create;
try
adsObj.Connection := adoConn;
adsObj.CommandText := SQLText;
adsObj.Open;
if adsObj.IsEmpty then
Exit;
sFile := TempFileName;
adsObj.SaveToFile(sFile);
//使用文件中转,牺牲了一些效率
adsObj.Close;
M.LoadFromFile(sFile);
StreamToVariant(M, Result);
DeleteFile(sFile);
finally
SetAbort;
adsObj.Free;
M.Free;
end;
end;
{通过MIDAS返回记录集}
function TChainGSPRDM.GetDataSetEx(iClientID: Integer;
const SQLText: WideString): OleVariant;
var
adsObj: TADODataSet;
dspObj: TDataSetProvider;
begin
Result := Null;
InitByClient(iClientID);
adsObj := TADODataSet.Create(nil);
dspObj := TDataSetProvider.Create(nil);
try
adsObj.Connection := adoConn;
adsObj.CommandText := SQLText;
dspObj.DataSet := adsObj;
adsObj.Open;
if adsObj.IsEmpty then
Exit;
Result := dspObj.Data;
//从ADO数据集到DataSetProvider.Data的转换最耗时间
adsObj.Close;
finally
SetAbort;
adsObj.Free;
dspObj.Free;
end;
end;
哪位大侠帮忙解决这个问题,300分奉上!