Login ProductsSalesSupportDownloadsAbout |
Home » Technical Support » ElevateDB Technical Support » Support Forums » ElevateDB General » View Thread |
Messages 1 to 10 of 31 total |
Faster Way to Retrieve Records? |
Thu, Apr 23 2015 1:37 AM | Permanent Link |
Steve Gill | I have some code similar to the simplified version shown below which is being used to retrieve data using a stored procedure.
for i := 0 to FStoredProcedure.RecordCount - 1 do begin Fullname := FStoredProcedure.FieldByName('Fullname').AsString; Address := FStoredProcedure.FieldByName('Address').AsString; Suburb := FStoredProcedure.FieldByName('Suburb').AsString; State := FStoredProcedure.FieldByName('State').AsString; FStoredProcedure.Next; end; There are over 6,000 records. It takes about 16 seconds to iterate through all of the records. Does anyone know if there is a faster way to retrieve the data? The stored procedure itself executes very quickly. It's the iterating through the records that takes time. I have tried using .Fields[0].AsString, etc., as well as persistent fields, but they seem to take the same amount of time. Thanks. = Steve |
Thu, Apr 23 2015 3:59 AM | Permanent Link |
Matthew Jones | Steve Gill wrote:
> I have tried using .Fields[0].AsString, etc., as well as persistent > fields, but they seem to take the same amount of time. That is what I was going to suggest - in my code that it time optimised I do the FieldByName and get a (pointer) to the TField object, and then refer to that directly. It used to be that it was faster. But if that is not making it faster, I'd make some good time measurements. If you can, I'd get http://www.nexusdb.com/support/index.php?q=qualitysuite which looks like it should do the business with LineTimer. (When they do resource checking too I'll be buying it, but the alternative AQTime product is very good but more expensive) Otherwise, do things like timing the initial call, each read, and then try dropping any special fields like blobs which may be needing a special call to get the data. If that changes anything, then you can consider if you need that data there and then. Basically, instrumentation until you work it out! -- Matthew Jones |
Thu, Apr 23 2015 5:57 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Steve
Bit out of the box here. Have a look at LIST. If you can go this way you'll get 4 fields holding what are effectively stringlists of your data. Stuff the info into stringlists so you can actually do something with it and iterate down the stringlists. Should be a lot faster. Roy Lambert |
Thu, Apr 23 2015 7:42 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Steve
Forget my idea Just tried it on my contacts database there's about 16k records SELECT LIST(COALESCE(_Surname,''),#13),LIST(COALESCE(_Forename,''),#13),LIST(COALESCE(_Town,''),#13),LIST(COALESCE(_County,''),#13) FROM Contacts vs SELECT _Surname,_Forename,_Town,_County FROM Contacts Q1 start: 23/04/2015 12:33:40 Q1 END: 23/04/2015 12:33:43 Q2 start: 23/04/2015 12:33:43 Q2 END: 23/04/2015 12:33:45 Q1 time: 3573 Q2 Time: 1170 SL Start: 23/04/2015 12:33:45 SL END: 23/04/2015 12:33:45 LOOP Start: 23/04/2015 12:33:45 LOOP END: 23/04/2015 12:33:45 SL time: 15 Loop Time: 125 OVERALL Q1 & SL time: 3588 Q2 & Loop Time: 1295 I've used the fastest way of addressing fields - by their index, and a sensitive result set. Other suggestions is to make sure the SP isn't hooked up to ANY visual controls - that will really slow it down. However, since you're taking 50% longer on less than half the data I suspect its what you're assigning to having an impact - either that or you have a slower machine, or both, Roy Lambert procedure TForm1.Button1Click(Sender: TObject); var t1, t2, t3, t4, t5, t6, t7, t8: integer; surname, forename, town, county: string; cntr: integer; sl1, sl2, sl3, sl4: TStringList; begin memo1.lines.Clear; memo1.lines.add('Q1 start: ' + Datetimetostr(Now)); t1 := gettickcount; Qry1.Open; t2 := gettickcount; memo1.lines.add('Q1 END: ' + Datetimetostr(Now)); memo1.lines.add('Q2 start: ' + Datetimetostr(Now)); t3 := gettickcount; Qry2.Open; t4 := gettickcount; memo1.lines.add('Q2 END: ' + Datetimetostr(Now)); Memo1.lines.Add(''); Memo1.lines.Add('Q1 time: ' + IntToStr(t2 - t1) + ' Q2 Time: ' + IntToStr(t4 - t3)); Memo1.lines.Add(''); memo1.lines.add('SL Start: ' + Datetimetostr(Now)); t5 := gettickcount; sl1 := TStringList.Create; sl2 := TStringList.Create; sl3 := TStringList.Create; sl4 := TStringList.Create; sl1.Assign(qry1.Fields[0]); sl2.Assign(qry1.Fields[1]); sl3.Assign(qry1.Fields[2]); sl4.Assign(qry1.Fields[3]); for Cntr := 0 to sl1.Count - 2 do begin surname := sl1[Cntr]; forename := sl2[Cntr]; town := sl3[Cntr]; County := sl4[cntr]; end; sl1.Free; sl2.Free; sl3.Free; sl4.Free; t6 := gettickcount; memo1.lines.add('SL END: ' + Datetimetostr(Now)); memo1.lines.add('LOOP Start: ' + Datetimetostr(Now)); t7 := gettickcount; qry2.First; while not qry2.Eof do begin surname := qry2.Fields[0].asString; forename := qry2.Fields[1].asString; town := qry2.Fields[2].asString; county := qry2.Fields[3].asString; qry2.Next; end; t8 := gettickcount; memo1.lines.add('LOOP END: ' + Datetimetostr(Now)); Memo1.lines.add(''); Memo1.lines.Add('SL time: ' + IntToStr(t6 - t5) + ' Loop Time: ' + IntToStr(t8 - t7)); Memo1.lines.add(''); Memo1.lines.add('OVERALL'); Memo1.lines.Add('Q1 & SL time: ' + IntToStr((t2 - t1) + (t6 - t5)) + ' Q2 & Loop Time: ' + IntToStr((t4 - t3) + (t8 - t7))); end; |
Thu, Apr 23 2015 9:50 AM | Permanent Link |
Ideal Software Systems | You will see about a 20% improvement just by recompiling in XE8 due to the changes in how values are read and written in TField.
Steve Gill wrote: I have some code similar to the simplified version shown below which is being used to retrieve data using a stored procedure. for i := 0 to FStoredProcedure.RecordCount - 1 do begin Fullname := FStoredProcedure.FieldByName('Fullname').AsString; Address := FStoredProcedure.FieldByName('Address').AsString; Suburb := FStoredProcedure.FieldByName('Suburb').AsString; State := FStoredProcedure.FieldByName('State').AsString; FStoredProcedure.Next; end; There are over 6,000 records. It takes about 16 seconds to iterate through all of the records. Does anyone know if there is a faster way to retrieve the data? The stored procedure itself executes very quickly. It's the iterating through the records that takes time. I have tried using .Fields[0].AsString, etc., as well as persistent fields, but they seem to take the same amount of time. Thanks. = Steve |
Thu, Apr 23 2015 10:10 AM | Permanent Link |
Terry Swiers | Hi Steve,
Calling DisableControls before processing the loop will help some. FStoredProcedure.DisableControls; <<< <your loop here> FStoredProcedure.EnableControls; <<< --------------------------------------- Terry Swiers Millennium Software, Inc. http://www.1000years.com http://www.atrex.com --------------------------------------- |
Thu, Apr 23 2015 11:32 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | >You will see about a 20% improvement just by recompiling in XE8 due to the changes in how values are read and written in TField.
That must be a first Roy |
Thu, Apr 23 2015 6:00 PM | Permanent Link |
Steve Gill | Thanks for all of the suggestions. The stored procedure isn't connected to any visual controls. The stored procedure itself takes less than a second to execute. It's the looping through the field values that takes all of the time.
I don't have XE8 yet so I can try that. I'll keep playing around with the code to see if I can speed it up. Thanks again. = Steve |
Fri, Apr 24 2015 12:44 AM | Permanent Link |
Steve Gill | Oops, that was meant to say "I don't have XE8 yet so I can't try that".
= Steve |
Fri, Apr 24 2015 2:14 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Steve
>Thanks for all of the suggestions. The stored procedure isn't connected to any visual controls. The stored procedure itself takes less than a second to execute. It's the looping through the field values that takes all of the time. Interesting. That's not what I found so it looks as though it could be whatever it is you're assigning to, or you can navigate a query much faster than an SP. Out of interest what is it you're actually assigning to? It can't just be a simple string which is what I used - can it? Also if you have the time try using a simple query rather than an SP Roy Lambert |
Page 1 of 4 | Next Page » | |
Jump to Page: 1 2 3 4 |
This web page was last updated on Tuesday, April 30, 2024 at 03:55 PM | Privacy PolicySite Map © 2024 Elevate Software, Inc. All Rights Reserved Questions or comments ? E-mail us at info@elevatesoft.com |