azyk wrote: ↑Thu 20 Dec 2018 14:40
Ivan_Carpio89 wrote: ↑Wed 19 Dec 2018 14:44
Okay. It is complicated for me, because I have tables with more than 1 million records, and to be activating TUniTable's is slow because the SQL sentences take time. Also the memory of my application grows to 1.5 GB only by activating TUniTable, this is why all the records in the table are brought to memory.
Any suggestions with the use of the TUniTable, or any recommendation of another equivalent component in UniDAC?
Please set the credentials in the UniDAC_SmartFetch console application and run it. Tell us about the results.
Code: Select all
program UniDAC_SmartFetch;
{$APPTYPE CONSOLE}
{$R *.res}
uses
SysUtils,
UniProvider,
SQLServerUniProvider,
Uni,
ActiveX,
psAPI,
Winapi.Windows;
var
Con: TUniConnection;
UniTable: TUniTable;
function CurrentProcessMemoryMB: Cardinal;
var
MemCounters: TProcessMemoryCounters;
begin
MemCounters.cb := SizeOf(MemCounters);
if GetProcessMemoryInfo(GetCurrentProcess,
@MemCounters,
SizeOf(MemCounters)) then
Result := MemCounters.WorkingSetSize div (1024*1024)
else
RaiseLastOSError;
end;
begin
CoInitialize(nil);
try
Con := TUniConnection.Create(nil);
try
Con.ProviderName := 'SQL Server';
// Set up credentials here
Con.Server := 'XXXXX';
Con.Database := 'XXXXX';
Con.Username := 'XXXXX';
Con.Password := 'XXXXX';
Con.Connect;
UniTable := TUniTable.Create(nil);
try
UniTable.Connection := Con;
UniTable.SmartFetch.LiveBlock := False;
UniTable.SmartFetch.Enabled := False;
UniTable.SpecificOptions.Values['SQL Server.FetchAll'] := 'True';
UniTable.FetchRows := 25;
UniTable.SQL.Text := 'select * from MyTable';
UniTable.Active:= True;
while not UniTable.eof do begin
UniTable.Next;
UniTable.Fields[0].Value;
end;
Writeln(Format('SmartFetch=False. Memory usage=%d Mb', [CurrentProcessMemoryMB]));
finally
UniTable.Free;
end;
UniTable := TUniTable.Create(nil);
try
UniTable.Connection := Con;
UniTable.SmartFetch.LiveBlock := True;
UniTable.SmartFetch.Enabled := True;
UniTable.SpecificOptions.Values['SQL Server.FetchAll'] := 'False';
UniTable.FetchRows := 25;
UniTable.SQL.Text := 'select * from MyTable';
UniTable.Active:= True;
while not UniTable.eof do begin
UniTable.Next;
UniTable.Fields[0].Value;
end;
Writeln(Format('SmartFetch=True. Memory usage=%d Mb', [CurrentProcessMemoryMB]));
finally
UniTable.Free;
end;
finally
Con.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Writeln('Press ENTER to exit.');
Readln;
end.
Hello, I already did the test, I added that I obtained the duration of the test, and the result was the following:
Duration = 00:01:24.244. SmartFetch = False. Memory usage = 4633 Mb
Duration = 00:07:47,482. SmartFetch = True. Memory usage = 1614 Mb
I observe the following:
1.- With Smart Fetch the memory went down from 4.6 GB to 1.6 GB.
2.- The duration increased, going from 1 minute to 7 minutes. This has its explanation since now it consults the fields of the table for every 25 rows.
Doubt:
1.- If the table is in constant change, that is, is being affected by INSERT's, UPDATE's and DELETE's, have you considered that the WHERE was as follows ?:
Code: Select all
SELECT *
FROM MyTable
WHERE (PK_FIELD1 =: p1 AND PK_FIELD2 =: p2 AND PK_FIELD3>: p3) OR
(PK_FIELD1 =: p1 AND PK_FIELD2>: p2) OR
(PK_FIELD1>: p1)
ORDER BY PK_FIELD1 ASC, PK_FIELD2 ASC, PK_FIELD3 ASC
OFFSET 0 ROWS FETCH FIRST 100 ROWS ONLY
My question is why the logic of the TUniTable with SmartFetch in True, from what I understand is:
1.- Get all the rows of the table, only by consulting the fields of the primary key.
2.- In each Next the fields of the first 25 rows are obtained, and so on for every 25 rows traveled.
I commented to you the first thing I'm looking for is that when I migrate from TFDTable to TUniTable, I have the lowest
cost in having to change our code in our projects, because they are large projects (in source code).
Now, in the future we are changing the use of the TFDTable by TFDQuery, to only consult what is used
in each function that we have, but at the moment it is a change that is in transition, and we are doing it little by little, that is why I am reviewing which configuration in the TUniTable is the most viable, or which component of the UniDAC to use, that we are interested in using the UniDAC components.
Regards!