SO, I managed to get de multirecords update working. This already saves a lot of insertion and updating time.
But here's the next bottleneck.

When TCLientDataset.ApplyUpdates is called, updates are commited to the TOraTable using the ORAProvider. Which works just fine.
However, after applying each update, the datasetprovider obviously performs a locate call on the TOraTable, and this again causes TMemData.PrepareRecNoCache to be fired.
When the record count increases, the insert performance gradually decreases from rocketing 10K rps (100 records inserted) downto a snail speed 20 rps (60K records inserted).
Profiling the app reveals 99% of the cpu time is spent in the routine TMemData.PrepareRecNoCache, which is called for each locate call, and FRecordNoCache is flushed for each post/delete.

How can I avoid this performance issue whilst keeping the multi-record updates
** EDIT **
I Managed to work around it by applying some patches. First of all I added a line to
Code: Select all
procedure TCustomDADataSet.SetUniDirectional(Value: boolean);
begin
if Value FUniDirectional then
begin
CheckInactive;
// HH Modification to notify unidirectional for TDataset base class
inherited SetUniDirectional(Value);
// HH End modification
FUniDirectional := Value;
if FIRecordSet nil then
FIRecordSet.SetProp(prUniDirectional, FUniDirectional);
if FUniDirectional then
FetchAll := False;
end;
end;
And next I added
Code: Select all
if IsUniDirectional then
begin
Result:=False;
Exit;
end;
To all TMemDataset.Locate implementations. It shopuld also be for findkey and findnearest, but for now I omitted this.
I cannot exactly predict all the implications, but for now this seems to fix my Update bottleneck problem
***EDIT***
I managed to bypass the obsolete locate by implementing my own dataset provider and resolver. All I did was override like this:
Code: Select all
procedure TSGORADataSetResolver.InternalBeforeResolve(Tree: TUpdateTree);
begin
if Tree.Delta.UpdateKindDB.ukInsert then
inherited; // inherited tries to locate the record. This makes no sense for inserted records
end;
Well, off course this wont fix an issue when many records are updated or deleted, and locate has to be called. In that case, the old problem with PrepareRecNoCache will turn up again. It's up to devart to faind a way to maintain the recno cache rather than destroy it for each post/delete and rebuild it for each locate.
Kind regards - Hans