我一直在尝试从Delphi程序(使用Delphi 2007)从MSSQL服务器检索数据。 到目前为止,该程序一直使用TADODataset来检索数据。在测试期间,我们发现使用ODBC提供程序的TQuery可以更快地获取大量数据。 但另一方面,TADODataset通过参数化+准备选择预先形成得更好。 TADODataset和TQuery都连接到同一个MSSQL数据库表。对于这个实验,我使用MSSQL Native Client作为两者的提供者。 TADODataset设置了一个到数据库的连接字符串,TQuery使用带有ODBC连接的TDatabase。
以下是实验中的一些代码:
procedure TForm2.Button1Click(Sender: TObject);
begin
ADODataSet1.CommandText := 'select top 100000 '+FDataFields+' from transactions';
GetData(ADODataSet1);
ReadData(ADODataset1);
ADODataSet1.Close;
end;
procedure TForm2.Button2Click(Sender: TObject);
var
I: Integer;
begin
ADODataSet1.CommandText := 'select '+FDataFields+' from transactions where originaltransno = :FieldValue order by Key2';
ADODataSet1.Parameters[0].Value := '000';
ADODataSet1.Prepared := True;
GetData(ADODataSet1);
for I := 0 to 2000 do
begin
ADODataSet1.Parameters[0].Value := '123';
//no match in DB, just a check if it is there
ADODataSet1.Requery;
ReadData(ADODataset1);
end;
ADODataSet1.Close;
ADODataSet1.Prepared := False;
end;
procedure TForm2.Button3Click(Sender: TObject);
begin
Query1.SQL.Clear;
Query1.SQL.Add('select top 100000 '+FDataFields+' from transactions');
GetData(Query1);
ReadData(Query1);
Query1.Close;
end;
procedure TForm2.Button4Click(Sender: TObject);
var
I: Integer;
begin
Query1.SQL.Clear;
Query1.SQL.Add('select '+FDataFields+' from transactions where originaltransno = :FieldValue order by Key2');
Query1.Params[0].Value := '000';
Query1.Prepare;
GetData(Query1);
for I := 0 to 2000 do
begin
Query1.Params[0].Value := '123';
Query1.Close;
Query1.Open;
ReadData(Query1);
end;
Query1.Close;
Query1.UnPrepare;
end;
procedure TForm2.GetData(ADataSet: TDataSet);
begin
ADataSet.DisableControls;
ADataSet.Open;
end;
procedure TForm2.ReadData(ADataSet: TDataSet);
begin
while not ADataSet.EOF do
begin
ReadLine(ADataSet);
ADataSet.Next;
end;
end;
function TForm2.ReadLine(ADataSet: TDataSet): string;
var
I: Integer;
begin
for I := 0 to ADataSet.Fields.Count - 1 do
begin
if ADataSet.FieldDefs[I].DataType = ftString then
Result := Result + ADataSet.Fields[I].AsString;
end;
end;
粗略计时(使用任务管理器中的CPU时间)
进一步的测试表明,大型TADODataset选择的缓慢时间来自于读取字段AsString 我尝试更换ReadLine:
function TForm2.ReadLine(ADataSet: TDataSet): int64;
var
I: Integer;
begin
for I := 0 to ADataSet.Fields.Count - 1 do
begin
if ADataSet.FieldDefs[I].DataType = ftInteger then
Result := Result + ADataSet.Fields[I].AsInteger;
end;
end;
有了整数读数,我得到了这些时间:
我尝试使用Value,但是"添加"字符串的Variant要慢得多
我可以在读取加速TADODataset读取的字符串时做些什么吗?