Disabling the disk flush
To change the main SQLite3 engine synchronous parameter, you may code for instance:
Client := TSQLRestClientDB.Create(Model,nil,MainDBFileName,TSQLRestServerDB,false,'');
Client.Server.DB.Synchronous := smOff;
Note that this setting is common to a whole TSQLDatabase
instance, so will affect all tables handled by the
TSQLRestServerDB
instance.
But if you defined some SQLite3 external tables, you can define the setting for a particular external connection, for instance:
Props := TSQLDBSQLite3ConnectionProperties.Create(DBFileName,'''',''); VirtualTableExternalRegister(Model,TSQLRecordSample,Props,'SampleRecord'); Client := TSQLRestClientDB.Create(Model,nil,MainDBFileName,TSQLRestServerDB,false,''); (Props.MainConnection as TSQLDBSQLite3Connection).Synchronous := smOff;
Now, some data, created with the latest version of our benchmark sample.
Insertion speed
SQLite3 (file full) |
SQLite3 (file off) |
SQLite3 (mem) |
TObjectList (static) |
TObjectList (virtual) |
SQLite3 (ext file full) |
SQLite3 (ext file off) |
SQLite3 (ext mem) |
Oracle | Jet | |
Direct | 8 | 369 | 30342 | 97170 | 94820 | 9 | 376 | 27360 | 499 | 657 |
Batch | 8 | 215 | 37326 | 147710 | 148266 | 9 | 225 | 33594 | 54469 | 758 |
Trans | 12920 | 35043 | 35414 | 98052 | 99633 | 12693 | 30387 | 30337 | 699 | 914 |
Batch Trans | 15542 | 41792 | 45495 | 141262 | 146019 | 14667 | 37436 | 39583 | 53604 | 916 |
You can note that the writing speed has been increased to about 400 objects
per second with Synchronous := smOff
, and is now at the level of
Oracle, as stated by "SQLite3 (file off)" and "SQLite3 (ext file off)
columns.
Even within a transaction, write speed increased by a factor of two. Worth a
try, isn't it?
Read speed
Here are the corresponding read speed.
Unsurprisingly, changing the synchronization from smFull
to
smOff
does not affect the reading speed.
SQLite3 (file full) |
SQLite3 (file off) |
SQLite3 (mem) |
TObjectList (static) |
TObjectList (virtual) |
SQLite3 (ext file full) |
SQLite3 (ext file off) |
SQLite3 (ext mem) |
Oracle | Jet | |
By one | 10548 | 10652 | 44166 | 98681 | 100066 | 45278 | 45111 | 47561 | 1026 | 1100 |
All Virtual | 161191 | 159012 | 169526 | 234951 | 110867 | 92733 | 95181 | 97108 | 58471 | 53602 |
All Direct | 169715 | 162855 | 169756 | 233688 | 242907 | 162142 | 163532 | 167790 | 89247 | 76022 |
We did make some small code enhancements for speed, in the JSON serializer
for instance, since the previous framework release.
So all results, including TObjectList
, did even increase a
little bit.
Conclusion: do your homework, i.e. do your backup
By default, the slow but truly ACID
setting will be used with
mORMot, just as usual.
We do not change this policy, since it will ensure best safety, in the expense
of slow writing outside a transaction.
If you can afford loosing some data in very rare border case, or if you are
sure your hardware configuration is safe (e.g. if the server is connected to a
power inverter and has RAID disks) and that you have backups at hand, setting
Synchronous := smOff
would help your application scale. Consider
using an external and dedicated database (like Oracle or MS SQL) if
your security expectations are very high, and if the default Synchronous
:= smFull
safe but slow setting is not enough for you.
In all cases, do not forget to perform backups as often as possible (at
least several times a day). You may use TSQLRestServerDB.Backup
or
TSQLRestServerDB.BackupGZ
methods for a fast backup of a running
database. Adding a backup feature on the server side is as simple as
running:
Client.Server.BackupGZ(MainDBFileName+'.gz');
Server will stop working during this phase, so a lower-level backup mechanism could be used instead, if you need 100% of service availability. Using an external database would perhaps keep you main mORMot database small in size, so that its backup time will remain unnoticeable on the client side.
Feedback is welcome on our forum.