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_COUNTING
并AdsFreshRecordCount
设置为False
.