快速SQL查询但结果检索速度慢

And*_*rla 6 delphi advantage-database-server

我正在使用Sybase的Advantage Database Server,目前还有一个很快的快速连接查询,运行速度非常快.问题是在运行查询后我想将结果放入一个字符串中.我检索了55000个条目的数据集.现在最多需要16秒.将它放入字符串中.我的查询只花了8毫秒才能运行.我的第一个尝试是这样的:

    aADSQuery.Open
    aADSQuery.First
    WHILE not aADSQuery.eof do
    begin
       s := s + aADSQuery.FieldbyName('Name').asString+',';
       aADSQuery.Next;
    end;
Run Code Online (Sandbox Code Playgroud)

之后,我试着避免使用aADSQuery.next,但是aADSQuery.RecordCount花了我9秒.

    aADSQuery.Open
    aADSQuery.First
    Count := aADSQuery.RecordCount;
    for i:=0 to count-1 do
    begin
      aADSQuery.RecNo := i;
      aADSQuery.FieldbyName('Name').AsString; 
    end;
Run Code Online (Sandbox Code Playgroud)

数据库已编制索引,条目ID为主键,其他列为indizes.我考虑创建一个视图来计算我的条目以避免记录计数,这可能与sql计数完全相同.但是视图中的条目计数与之前的时间相同.如果我在基表上使用带有130000个条目的sql计数,则只需要200 ms.但是,如果我对结果表进行计数,而不使用视图则需要9秒.我觉得它是,因为没有新的临时结果表的indizes.有谁知道如何以正确的方式处理这类问题或如何获得更快的结果计数?

非常感谢你

kob*_*bik 13

使用一些基于缓冲区的类,例如TStringStream填充字符串.这样可以避免String连接缓慢重新分配(s := s + foo).

不要aADSQuery.FieldbyName('Name').AsString在循环中使用.这很慢.而是F像这样创建一个局部变量:

var
  F: TField;

F := aADSQuery.FieldbyName('Name');
for i:=0 to count-1 do
begin
  aADSQuery.RecNo := i;
  F.AsString; 
end;
Run Code Online (Sandbox Code Playgroud)

我认为使用aADSQuery.Next比使用更快RecNo

procedure Test;
var
  F: TField;
  Buf: TStringStream;
  S: string;
begin
  aADSQuery.DisableControls;
  try
    aADSQuery.Open;
    F := aADSQuery.FieldbyName('Name');
    Buf := TStringStream.Create('');
    try
      while not aADSQuery.Eof do
      begin
        Buf.WriteString(F.AsString + ',');
        aADSQuery.Next;
      end;
      S := Buf.DataString;
    finally
      Buf.Free;
    end;
  finally
    aADSQuery.EnableControls;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

您可以在服务器端生成该字符串并将其返回到客户端,而无需在客户端构造任何字符串:

DECLARE @Names NVARCHAR(max)
SELECT @Names = ''
SELECT @Names = @Names + ',' + ISNULL([Name], '') FROM MyTable
SELECT @Names
Run Code Online (Sandbox Code Playgroud)

您还可以通过设置来优化性能TAdsQuery.AdsTableOptions.确保AdsFilterOptions设置为IGNORE_WHEN_COUNTINGAdsFreshRecordCount设置为False.

  • +1使用本地字段变量!但Delphi的字符串分配速度慢吗?在一篇关于TStringBuilder的文章中我读到它实际上非常快(比TStringBuilder.Add快) (3认同)
  • @AndréDziurla,ADS Architect可能会异步获取结果.所以你看到7毫秒后的第一个结果集.它可能正在使用服务器端游标,因此它在7毫秒后完成,并在向下滚动网格时获取其余记录.另一方面,您正在使用同步查询,将所有55000发送到客户端.并加上收缩字符串. (3认同)