The results of my tests using fmOnDemand
with postgreSQL and MySQL are basically the same. With FDTable fmOnDemand
only downloads what it needs limited to the RowSetSize
. With a RowSetSize
of 50 it initially downloads 50 tuples and no matter where you scroll to it never downloads more than 111 tuples (though doubtless that is dependent on the size of the connected DBGrid
. If you disconnect the FDTable
from a data source it initially downloads 50 tuples and if you then navigate to any record in the underlying table it downloads one tuple only and discards all other data.
FDQuery
in fmOnDemand
downloads only the initial 50 tuples when opened, but if you navigate by RecNo
it downloads every tuple in between. I had rather hoped it would use LIMIT and OFFSET commands to get only records that were being requested.
To recreate the test for PostGre you need the following FireDAC components:
object FDConnectionPG: TFDConnection
Params.Strings = (
'Password='
'Server='
'Port='
'DriverID=PG')
ResourceOptions.AssignedValues = [rvAutoReconnect]
ResourceOptions.AutoReconnect = True
end
object FDQueryPG: TFDQuery
Connection = FDConnectionPG
FetchOptions.AssignedValues = [evMode, evRowsetSize]
end
object FDTable1: TFDTable
CachedUpdates = True
Connection = FDConnectionPG
FetchOptions.AssignedValues = [evMode, evRowsetSize, evRecordCountMode]
FetchOptions.RecordCountMode = cmFetched
end
If you wish to recreate it with MYSQL, you will basically need the same FireDAC components, but the FDConnection
needs to be set as follows:
object FDConnectionMySql: TFDConnection
Params.Strings = (
'DriverID=MySQL'
'ResultMode=Use')
ResourceOptions.AssignedValues = [rvAutoReconnect]
ResourceOptions.AutoReconnect = True
end
You'll need an edit box, two buttons, a checkbox, a timer and a label and the following code:
procedure TfrmMain.Button1Click(Sender: TObject);
begin
if not FDQueryPG.IsEmpty then
begin
FDQueryPG.EmptyDataSet;
FDQueryPG.ClearDetails;
FDQueryPG.Close;
end;
if not FDTable1.IsEmpty then
begin
FDTAble1.EmptyDataSet;
FDTable1.ClearDetails;
FDTable1.Close;
end;
lFetched.Caption := 'Fetched 0';
lFetched.Update;
if cbTable.checked then
begin
FDTable1.TableName := '[TABLENAME]';
FDTable1.Open();
lFetched.Caption := 'Fetched '+ FDTable1.Table.Rows.Count.ToString;
end
else
begin
FDQueryPG.SQL.Text := 'Select * from [TABLENAME]';
FDQueryPG.open;
lFetched.Caption := 'Fetched '+ FDQueryPG.Table.Rows.Count.ToString;
end;
timer1.Enabled:=true;
end;
procedure TfrmMain.Button2Click(Sender: TObject);
begin
if cbTable.Checked then
FDTable1.RecNo := strToInt(Edit1.Text)
else
FDQueryPG.RecNo := strToInt(Edit1.Text);
end;
procedure TfrmMain.cbTableClick(Sender: TObject);
begin
timer1.Enabled := False;
end;
procedure TfrmMain.Timer1Timer(Sender: TObject);
begin
if cbTable.checked then
lFetched.Caption := 'Fetched '+ FDTable1.Table.Rows.Count.ToString
else
lFetched.Caption:='Fetched '+FDQueryPG.Table.Rows.Count.ToString;
lFetched.Update;
end;
fmOnDemand
, FireDAC fetches only at mostRowSetSize
number of tuples in this case. TheAutoFetchAll
option can affect fetching of all tuples only in special cases. I assume that you onlyOpen
the cursor and iterate through the resultset to fetch another batch. Could we have a MCVE with details about DBMS, please? Also, how do you measure how many tuples is fetched in the storage? - VictoriafmOnDemand
. With the query's ` FetchOptions` set as in original post, I runFDQuery.open
and then iterate as assumed. The call toOpen
returns the correctRecordCount
, but fetches all tuples ie 25000 odd. I check this by re-running the query with itsRecordCountMode
set tocmFetched
. If in addition, I setRecsMax
to 500 then setRecordCountMode
tocmFetched
it reports 500 tuples fetched as expected, and when re-run set tocmTotal
it reports 500 tuples not the expected 25000. - Mark Williams