views:

729

answers:

5
+2  Q: 

Delphi ADO Query

Hi. Is there any faster way to iterate through an ADO Dataset than

while (not ADOQuery1.Eof) do
    begin
      /* Do something */
      ADOQuery1.Next;
    end;

I need to scan a dataset of around 9000 items and only extract records matching a pre-defined set of branch numbers.

Thanks, Pieter.

+6  A: 

@Pieter, two options

1) you can modify your sql sentence before to execute, adding the where condition wich match with the pre-defined set of branch numbers.

2) using the Filter property of TAdoQuery.

AdoQuery1.close;
AdoQuery1.filter := 'your condition goes here';
AdoQuery1.filtered := true;
AdoQuery1.Open;
RRUZ
He's right. The fastest way to accomplish this is to use a WHERE clause in the SQL so it only returns the records you need. SQL is specifically optimized for doing this and it's likely to do a better job than anything you can do client-side.
Mason Wheeler
+4  A: 

It is much faster to use ADORecordset for such tasks:

 while not ADOQuery1.Recordset.EOF do
  begin
    ADOQuery1.Recordset.MoveNext;
    // get value
    SomeVar := ADOQuery1.Recordset.Fields['FieldName'].Value;  
  end;
Linas
Is that true? I figured that the .next .eof and .fields calls would just go to the recordset object anyway.
MarkF
You are right, but controlling recordset directly is much faster, because dataset does lots of other stuff which slows down iteration.
Linas
This will provide a bit of a speed boost, but probably not as much as not having to iterate over as many records in the first place.
Mason Wheeler
Well, 9000 - not so many records, but I can bet that recordset would outperform dataset at least 4 times.
Linas
This is also dependant on DisableControls as noted by Neftali. ADO datasets are very slow if it isn't called. It is only needed if you have data bound controls.
Gerry
DisableControls and using RecordSet has definately increased the speed in which we now process the records! Thank you for all the tips. Regards, Pieter.
Pieter van Wyk
+4  A: 

Be sure that you use DisableControls/EnableControls if it's not necesary for not spend time updating visible controls associated at DataSet.

try
  ADOQuery1.DisableControls;
  while (not ADOQuery1.Eof) do
    begin
      /* Do something */
      ADOQuery1.Next;
    end;
finally
  ADOQuery1.EnableControls;
end;

Regards.

Neftalí
A: 

Additional performance gains can be made by avoiding any string comparisons until as late as possible (when everything else matches). If you have a large number of duplicate strings in your database, then consider placing your strings in a separate table, linked back to the first table by an integer.

skamradt
A: 

You may want to change the query to include a SQL where clause, something like

Select whatever fields From whatevertable
where branchnumber in (
    select branchnumber from whatevertable where branchid=xxz
)

I would also highly suggest looking at forward-only, read-only cursors to give the biggest speed increase.

Darian Miller