I'm so sorry. I apologize for not answering your questions and for not including in the test code the configuration you have recommended.
How did you insert those records?
Code: Select all
Query1.SQL.Text:= 'INSERT INTO tb_test_zeos (ID) VALUES (:PARAM_ID)';
For Id:= 1 To Records Do
Begin
Query1.ParamByName('PARAM_ID').AsInteger:= Id;
Query1.ExecSQL;
End;
Which Component did you use to insert the records?
TZQuery
MyDAC/Unidac. I know they are there .. that's all. Are those components unidirectional or do you have a scrollable cursor?
These components are not unidirectional.
In mORMot you just need forwardonly (unidirectional...
mORMot uses UTF8 only. Set your ZConnection.ControlsCodePage to cCP_UTF8, and switch off the TZConnection.AutoEncode modus. Open your MySQL connection with utf8mb4 or utf8(buggy for more than 4Byte encoded characters).
I'm not using mORMot yet, I'm starting the preliminary tests.
Code: Select all
procedure RunTest;
const Records = 100000;
var TimeBegin: TDateTime;
Id: Integer;
Log: TStringList;
Sum: Integer;
begin
ShowMessage('Begin test');
Log:= TStringList.Create;
try
{$IfDef Use_ZeosLib}
Connection1:= TZConnection.Create(Nil);
//ZConnection1.UseMetadata:= True;
Connection1.Properties.Add('UseResult=True');
Query1:= TZQuery.Create(Nil);
Query1.Connection:= Connection1;
Query1.Options:= Query1.Options - [doCalcDefaults];
Log.Append('Zeoslib ' + Connection1.Version);
with Connection1 do
begin
LibraryLocation:= ExtractFilePath(ExtractFileDir(Application.ExeName)) + 'libmySQL.dll';
Protocol:= 'mysql';
HostName:= 'localhost';
Port:= 3307;
User:= 'root';
Password:= '';
Database:= 'dbtestzeos';
Connect;
end;
Query1.SQL.Text:= 'TRUNCATE TABLE tb_test_zeos';
Query1.ExecSQL;
TimeBegin:= Now;
For Id:= 1 To Records Do
Begin
Query1.SQL.Text:= 'INSERT INTO tb_test_zeos (ID) VALUES (' + IntToStr(Id) + ')';
Query1.ExecSQL;
End;
Log.Append('Insert data, do not use prepared sql statement ' + IntToStr(MilliSecondsBetween(TimeBegin, Now)) + ' MilliSeconds');
// zeoslib-code-0-r5355-branches-testing-7.3 insert 3 records and raise Access violation at address 00000000 in module 'Test.exe'. Read of address 00000000.
Query1.SQL.Text:= 'TRUNCATE TABLE tb_test_zeos';
Query1.ExecSQL;
TimeBegin:= Now;
Query1.SQL.Text:= 'INSERT INTO tb_test_zeos (ID) VALUES (:PARAM_ID)';
Query1.ParamCheck:= True;
Query1.Prepare;
Try
For Id:= 1 To Records Do
Begin
Query1.ParamByName('PARAM_ID').AsInteger:= Id;
Query1.ExecSQL;
End;
Except On Error: Exception Do InputBox('', '', Error.Message);
End;
Log.Append('Insert data, use prepared sql statement ' + IntToStr(MilliSecondsBetween(TimeBegin, Now)) + ' MilliSeconds');
Sum:= 0;
TimeBegin:= Now;
Query1.SQL.Text:= 'SELECT ID FROM tb_test_zeos';
Query1.Open;
For Id:= 1 To Query1.RecordCount Do
Begin
Sum:= Sum + Query1.Fields[0].AsInteger;
Query1.Next;
End;
Log.Append('Select and sum data, use the RecordCount property ' + IntToStr(MilliSecondsBetween(TimeBegin, Now)) + ' MilliSeconds. Result ' + IntToStr(Sum));
Query1.Close;
Sum:= 0;
TimeBegin:= Now;
Query1.SQL.Text:= 'SELECT ID FROM tb_test_zeos';
Query1.Open;
While Not Query1.Eof Do
Begin
Sum:= Sum + Query1.Fields[0].AsInteger;
Query1.Next;
End;
Log.Append('Select and sum the data, do not use the RecordCount property ' + IntToStr(MilliSecondsBetween(TimeBegin, Now)) + ' MilliSeconds. Result ' + IntToStr(Sum));
Log.SaveToFile(ExtractFilePath(Application.ExeName) + FormatDateTime('yyyy-mm-dd hh-nn-ss.zzz', Now) + 'Zeoslib ' + Connection1.Version + '.txt');
{$Else}
Connection1:= TMyConnection.Create(Nil);
Query1:= TMyQuery.Create(Nil);
Query1.Connection:= Connection1;
Log.Append('MyDAC 5.20.0.11');
with Connection1 do
begin
Server:= 'localhost';
Port:= 3307;
Username:= 'root';
Password:= '';
Database:= 'dbtestzeos';
Connect;
end;
Query1.SQL.Text:= 'TRUNCATE TABLE tb_test_zeos';
Query1.Execute;
TimeBegin:= Now;
For Id:= 1 To Records Do
Begin
Query1.SQL.Text:= 'INSERT INTO tb_test_zeos (ID) VALUES (' + IntToStr(Id) + ')';
Query1.Execute;
End;
Log.Append('Insert data, do not use prepared sql statement ' + IntToStr(MilliSecondsBetween(TimeBegin, Now)) + ' MilliSeconds');
Query1.SQL.Text:= 'TRUNCATE TABLE tb_test_zeos';
Query1.Execute;
TimeBegin:= Now;
Query1.SQL.Text:= 'INSERT INTO tb_test_zeos (ID) VALUES (:PARAM_ID)';
Query1.ParamCheck:= True;
Query1.Prepare;
For Id:= 1 To Records Do
Begin
Query1.ParamByName('PARAM_ID').AsInteger:= Id;
Query1.Execute;
End;
Log.Append('Insert data, use prepared sql statement ' + IntToStr(MilliSecondsBetween(TimeBegin, Now)) + ' MilliSeconds');
Sum:= 0;
TimeBegin:= Now;
Query1.SQL.Text:= 'SELECT ID FROM tb_test_zeos';
Query1.Open;
For Id:= 1 To Query1.RecordCount Do
Begin
Sum:= Sum + Query1.Fields[0].AsInteger;
Query1.Next;
End;
Log.Append('Select and sum data, use the RecordCount property ' + IntToStr(MilliSecondsBetween(TimeBegin, Now)) + ' MilliSeconds. Result ' + IntToStr(Sum));
Query1.Close;
Sum:= 0;
TimeBegin:= Now;
Query1.SQL.Text:= 'SELECT ID FROM tb_test_zeos';
Query1.Open;
While Not Query1.Eof Do
Begin
Sum:= Sum + Query1.Fields[0].AsInteger;
Query1.Next;
End;
Log.Append('Select and sum the data, do not use the RecordCount property ' + IntToStr(MilliSecondsBetween(TimeBegin, Now)) + ' MilliSeconds. Result ' + IntToStr(Sum));
Log.SaveToFile(ExtractFilePath(Application.ExeName) + FormatDateTime('yyyy-mm-dd hh-nn-ss.zzz', Now) + ' MyDAC 5.20.0.11 ' + '.txt');
{$EndIf}
ShowMessage('Test finished');
finally
Log.Free;
Connection1.Free;
Query1.Free;
end;
end;
Delphi 7, Zeoslib 7.2.4-stable
Insert data, do not use prepared sql statement 25602 MilliSeconds
Insert data, use prepared sql statement 10580 MilliSeconds
Select and sum data, use the RecordCount property 325 MilliSeconds. Result 705082704
Select and sum the data, do not use the RecordCount property 311 MilliSeconds. Result 705082704
The performance is very good, but I don't know if it will be possible to configure it in mORMot without using the DB layer. I have to learn more.