#51 mORMot 1 » How to get a string copy of CreateSQLMultiIndex » 2021-10-03 14:43:26

wxinix
Replies: 4

When calling  TRestServerDB.CreateSQLMultiIndex and TRestServerDB.CreateMissingTables,  is it possible to obtain a string copy of the generated SQL script?

#52 mORMot 1 » How to correctly call TRestServerDB.TransactionBegin? » 2021-10-02 19:27:22

wxinix
Replies: 21

The second param of TRestServerDB.TransactionBegin is SessinID,

How can I get that SessionID?  (TRestClientDB provides SessionID, but I didn't find it from TRestServerDB).

#53 Re: mORMot 1 » Multi-threaded BatchAdd performance » 2021-10-02 04:29:44

It is not "Delphi Win64 is less good for internal SQLite 3 on my computer".  Actually, I did get the similar results using Delphi 10.4.2, x64,   when running the official test project https://github.com/synopse/mORMot2/blob … onsole.dpr .  Such results indicate Direct (internal) SQLite layer is faster then External SQLite layer, as you noted.

However, my updated test project  https://gist.github.com/wxinix/325c64a2 … 4ae02ff75f  indicates otherwise - that is,  External SQLite layer is faster than Direct SQLite layer.

I am happy with the good-enough performance either way. Just not sure what caused the difference.  If you could take a quick peek,  that would be great.  But if you are not interested, that is also fine.  Thanks again for you feedback and the continued performance improvements.

ab wrote:

I don't know why your Delphi Win64 is less good for the internal SQLite3 on your computer.
The external DB layer is very thin: most of the time is spent inside the SQlite3 engine itself. Our ORM is able to bypass the whole "external" layer. So it makes sense to have close numbers.

#54 Re: mORMot 1 » Multi-threaded BatchAdd performance » 2021-10-01 20:39:38

ab wrote:

I have fixed the sample.

And also rewritten some part of the ORM process for better performance.
Now the direct SQLite3 layer seems faster than the external SQLite3 layer for both reads and writes.
[

I rerun my test with the latest commit - quite contrary, it seems external SQLite3 layer is still much faster than direct SQLite3 layer for writes.  I am using Delphi 10.4.2, win64.

I noticed that in your sample code, https://github.com/synopse/mORMot2/blob … tCases.pas, TRestClientDB class is used, like below:

 
 TRestClientDB.Client.BatchStart
....
 TRestClientDB.Client.BatchAdd 
...
 TRestClientDB.Client.BatchSend

But in my testing code,  I use TRestServerDB class directly, together with TSQLRestBatch class:

 LBatch := TSQLRestBatch.Create
 ...
 LBatch.Add
 ...
 TRestServerDB.BatchSend(LBatch...

My question is - is the latest performance improvements only for TRestClientDB?  It seems TRestServerDB.BatchSend performance is not improved with the latest commits.

#55 Re: mORMot 1 » Multi-threaded BatchAdd performance » 2021-09-30 17:48:53

ab wrote:

In production, I would use the internal Sqlite3 engine for sure.
Especially with my latest commits.

Hi @ab  thank you for the latest commit, and advice.

In case of a real-time time-series database where WRITES (BatchAdd, every couple of seconds) are much more frequent than READS (every couple of minutes)  - is the internal SQLite engine's cache still working?  I think the cache would be less effective?

Thanks again.

#56 Re: mORMot 1 » Multi-threaded BatchAdd performance » 2021-09-30 13:31:18

ab wrote:

@wxinix
I just committed some code refactoring which enhanced performance on my side. Please check and see if it is better on your side.

HI @ab, @ttomas

Thank you for the advice and feedback.

I built with the latest commit - still it seems SQLite External File provides the best BatchAdd performance (~350k records/second).

There got to be some (nice) reason for such a stunning performance for an SQL DB. Regardless,  my goal is to find out which settings provides the best WRITE performance- given the testing results,  the answer appears to be SQLite External File .

Note - SQLite External File also gives very good READ performance (slightly worse than SQLite in Memory). So overall,  SQLite External File appears to be the best option?

Any comments? Insights or advice?

#57 Re: mORMot 1 » Multi-threaded BatchAdd performance » 2021-09-29 16:12:29

ab wrote:

This is not consistent with my previous finding about mORMot BatchAdd and previous benchmarks.

I don't have any idea why you find this.
Perhaps the Delphi Win64 memory manager is not very efficient? What if you try on Win32?

HI ab,  I uploaded the testing project to my github gist , you can try and see yourself.  In BOTH x86 and Win64 cases,  mORMot2 SQLite external file DB is much faster than the SQLite in memory DB.

Delphi 10.4.2, Win64 build,  results:

LServer_SQLiteMem.BatchSend   6001 records takes 21.60ms  (277785 records/second).
LServer_SQLiteExtFile.BatchSend 6001 records takes 16.84ms (356248 records/second).

Delphi 10.4.2, x86 build,  results:

LServer_SQLiteMem.BatchSend   6001 records takes 28.33ms  (211809 records/second).
LServer_SQLiteExtFile.BatchSend 6001 records takes 21.48ms (279363 records/second).

#58 Re: mORMot 1 » Multi-threaded BatchAdd performance » 2021-09-28 19:19:13

I continued with my performance testing - this time, I compared mORMot2  SQLite in memory vs mORMot2 External SQLite File DB.  I am very surprised that the External SQLite File DB is much faster than the SQLite in MEM DB - 25% faster!   

Note:
- For External SQLite File DB, I used TSQLDBSQLite3ConnectionProperties, and SynchronousMode := Off, and LockingMode := Exclusive
- Delphi 10.4.2,  Win64 Build

Details below - but does that make sense?  I expect the In-MEM DB faster than External File DB.

- Single Table,  Multi-Threaded, BatchAdd via a background worker thread,  the SQLite In MEM DB Results:

20210928 18564227  " debug Test_BatchAdd_STable_MThread_MemDB::thr_1 - Orm.Server.BatchSend 6000 records takes 22.54ms (266098 rec/sec), code 200
20210928 18564229  " debug Test_BatchAdd_STable_MThread_MemDB::thr_2 - Orm.Server.BatchSend 6000 records takes 23.09ms (259830 rec/sec), code 200
20210928 18564230  " debug Test_BatchAdd_STable_MThread_MemDB::thr_3 - Orm.Server.BatchSend 6000 records takes 23.42ms (256191 rec/sec), code 200

- Single Table,  Multi-Threaded, BatchAdd via a background worker thread, External SQLite File DB,  SynchronousMode := Off, LockingModel := Exclusive

20210928 18564257  " debug Test_BatchAdd_STable_MThread_SQLite::thr_1 - Orm.Server.BatchSend 6000 records takes 17.34ms (345861 rec/sec), code 200
20210928 18564258  " debug Test_BatchAdd_STable_MThread_SQLite::thr_3 - Orm.Server.BatchSend 6000 records takes 18.15ms (330578 rec/sec), code 200
20210928 18564259  " debug Test_BatchAdd_STable_MThread_SQLite::thr_2 - Orm.Server.BatchSend 6000 records takes 17.71ms (338676 rec/sec), code 200

#59 Re: mORMot 1 » Multi-threaded BatchAdd performance » 2021-09-24 00:22:43

ab wrote:

If you really need consistent write to PostgreSQL, I guess my shared TSQLRestBatch trick which is sent in a background thread may be the only solution.

Thank you ab, for the advice.

I implemented as advised - using a background worker thread to do the BatchAdd work, and rerun the test.

Note - I am using ZEOS for PostgreSQL connection.

The results are very satisfying.
- mORMot static object list   -  760,000 records/sec
- mORMot SQLite in-memory -  290,000 records/sec
- PostgreSQL                     -  110,000 records/sec


Should you be interested - the record type is defined as follows:

  TSQLRecordSample = class(TSQLRecord)
  strict private
    FAmount: Currency;
    FBirthDate: TDateTime;
    FCreatedAt: TCreateTime;
    FLastChange: TModTime;
    FName: RawUTF8;
  published
    property Amount: Currency read FAmount write FAmount;
    property BirthDate: TDateTime read FBirthDate write FBirthDate;
    property CreatedAt: TCreateTime read FCreatedAt write FCreatedAt;
    property LastChange: TModTime read FLastChange;
    property Name: RawUTF8 index 40 read FName write FName stored AS_UNIQUE;
  end;

#60 Re: mORMot 1 » Multi-threaded BatchAdd performance » 2021-09-24 00:18:31

mpv wrote:
wxinix wrote:

But,  PostgreSQL layer DROPS the single-threaded insertion rate from Zeo's 100,000 record/sec to about 50,000 records/sec

I think this depends on data you insert. ZEOS interally uses binary pg protocol, so if inserted data is mostly numbers it can be faster compared to mORMot Postgres layer, where text pg protocol is used

Thank you for the advice.  I'll keep this in mind. But for now - I'll stick to ZEOS, which seems has faster performance for my use case.

#61 Re: mORMot 1 » Potential bug? mormot.db.sql.postgres does not allow to set Port » 2021-09-23 14:51:06

ab wrote:

I have just included this "host:port" parsing.

Thank you it works.

#62 Re: mORMot 1 » Multi-threaded BatchAdd performance » 2021-09-23 14:42:34

Note - all the insertion cases are targeting ONE single table.  For each test case, the table will be emptied in advance.

----------------------------
1. What if you insert 150,000 records from three concurrent threads?
It doesn't change the overall average insert rate

2. What if you insert 50,000 records from one thread, but 3 times in a row?
Similar (slightly slower 1~2%) insertion rate,  compared to one-time 150,000 records.

3. What if you use our direct PostgreSQL layer instead of Zeos?
mORMot PostgreSQL layer IMPROVES the multi-threaded (3 threads) insertion rate by x6 times,  increasing from Zeo's 5000 records/sec to a much higher 30000 records/sec
But,  PostgreSQL layer DROPS the single-threaded insertion rate from Zeo's 100,000 record/sec to about 50,000 records/sec

4. What if you use SQLite3 instead of PostgreSQL?
If I use mORMOt internal in-mem SQLite3,  the multi-threaded insertions is about 4~6% FASTER then the single-thread insertion,  around 220,000 records/sec
If I use mORMot static object list,  the multi-threaded insertions is about 4~6% FASTER then the singled-thread insertion, around 500,000 records/sec
---------------------------

IN SUMMARY:
-  mORMot in-mem SQLite, and static object list:   multi-threaded batch insertion rate is FASTER than single-threaded insertion
-  for PostgreSQL,  Zeos has the best single-threaded batch insertion rate (100,000 records/sec),  mORMot Postgresql Layer has the best multi-threaded batch insertion rate (50,000 records/sec).

Are the above making sense?

#63 Re: mORMot 1 » Potential Bug? mormot.db.sql.postgres TSqlDBPostgresStatement.Execute » 2021-09-23 14:32:48

ab wrote:

You should rather try ExecuteNoResult() I guess for such statements with no result.

Thank you. Yes - that works.

#64 mORMot 1 » Potential Bug? mormot.db.sql.postgres TSqlDBPostgresStatement.Execute » 2021-09-23 12:28:53

wxinix
Replies: 2

mormot.db.sql.postgres, TSqlDBPostgresStatement.Execute

line 624

 fTotalRowsRetrieved := PQ.ntuples(fRes); 

Would throw Exception ESqlDBPostgres, with message
"TSqlDBPostgresStatement.ExecutePrepared: result expected but statement did not return tuples'.

The statement being executed is
fSql 'CREATE SCHEMA IF NOT EXISTS test'

#65 mORMot 1 » Potential bug? mormot.db.sql.postgres does not allow to set Port » 2021-09-23 12:21:40

wxinix
Replies: 4

Line 293 of mormot.db.sql.postgres

fPGConn := PQ.SetDBLogin(pointer(Properties.ServerName), nil, nil, nil,  pointer(Properties.DatabaseName), pointer(Properties.UserID),
      pointer(Properties.PassWord));

When Propertyies.ServerName is set to be "localhost:5432" , it will thrown exception "Connection to database postgres failed [could not translate host name "localhost:5432" to address: Unknownhost]'.

To make it work,  Properties.ServerName must NOT include the port, like this "localhost".  Port cannot be specified as part of the ServerName.

The second parameter of libpq API,  PQ.SetDBLogin is actually for specifying the port. But it is not used by mORMot (i.e., nil for the default 5432)

Hence,  this is a missing piece here that a user cannot specify a port other than the default 5432.

#66 mORMot 1 » Multi-threaded BatchAdd performance » 2021-09-23 03:57:18

wxinix
Replies: 26

Follwing  this post about the thread-safe of TRestServerDB, I did some test about multi-threaded BatchAdd.

The database is PostgreSQL, and I use TSQLDBZEOSConnectionProperties

Test 1:  I use TRestServerDB.BatchAdd  to insert 150,000 records into one table in a single thread
Test 2:  I use TRestServerDB.BatchAdd to insert 50,000 records in the the same table, but from three different concurrent threads

Both Test 1, and Test 2 uses the SAME instance of TRestServerDB.

Test1:  is quite fast, achieving a rate of 100,000 records/second
Test2: very slow,  the overall rate is 5000 records/second

Is this expected?  Any tricks to improve the multi-threaded Batch insert?

Note - If I split the data into three different tables (i.e., the same table structure but diff table names) - the results are still similar.  Multi-threaded insert is very slow.

#67 Re: mORMot 1 » mORMot2 performance on Win x64 » 2021-09-21 15:19:50

ab wrote:

I would use the default memory manager on Delphi, and mORMot x86_64 memory manager on FPC.

You may try our mORMot x86_64 memory manager on Delphi Win64, which has less collisions for smallest memory blocks, so may be a bit faster on heavily multi-thread process.

Thank you again, ab!

I run another around of tests using the following Mem Manager:

Delphi Default
FastMM4-AVX
mormot.core.fpcx64mm
FastMM5


Delphi 10.4.2, Windows Server 2016, and x64 Release Build

And I found that FastMM5 would give the best performance, for both Multi, and Single thread.
FastMM5 > FastMM4-AVX > Delphi MM/mormot.core.fpcx64mm

#68 Re: mORMot 1 » mORMot2 performance on Win x64 » 2021-09-21 12:46:39

ab wrote:

On my PC, the regression tests are faster on Win64 than Win32.

So if your app is significantly slower on Win64, my guess is that it does not come from normal work of the framework, but on your use case.
Enable the logs, or try to do some profiler, to find out what is actually slower.

Which compiler do you use? Which Memory Manager?

Thank you ab for the heads up.

I use Delphi 10.4.2, and FastMM4-AVX memory manager (https://github.com/maximmasiutin/FastMM4-AVX), Release build.  But my previous test mistakenly enabled FullDebugMode for the RELEASE build.

Now that with your reminder,  I disabled FullDebugMode.  And re-run the test (using the Static Object List DB)

x86
Single Thread                  : 440842 records/sec inserts
Multi Thread (2 threads)    : 474982 records/sec inserts

x64:
Single Thread                  : 471051 records/sec inserts
Multi Thread (2 threads)    : 486679 records/sec inserts

So, in my case,  using Delphi default MM,
Single Thread,   x64 is 7.0% FASTER than 32bit
Multi   Thread,   x64 is 2.5% FASTER than 32 bit.

So you are right, x64 is indeed somewhat faster than x86.

Question - do you have any recommendation for memory manager to use?  Thank you again.

#69 mORMot 1 » mORMot2 performance on Win x64 » 2021-09-21 00:04:09

wxinix
Replies: 9

I found mormot2 seems to be significantly slower with x64 built

The same application in x86 (32bit) build is almost 2 times faster then its x64 built.  Is this expected?

In other words,  is x86 (32bit) preferred for performance oriented application?

#70 Re: mORMot 1 » mormot.core.log - EventArchiveSynLZ bug? » 2021-09-17 13:25:00

I changed back to FastMM4-AVX , and things seem to be working normal again.

#71 Re: mORMot 1 » mormot.core.log - EventArchiveSynLZ bug? » 2021-09-17 11:45:41

ab wrote:

TAlgoSynLZ.AlgoCompressDestLen exists.

@ab - you are right.

I found the problem - it is related to FastMM5.

At  mormot.core.buffers line 5276

    if {%H-}dst = '' then
      SetString(dst, nil, AlgoCompressDestLen(Head.UnCompressedSize));

If FastMM5 is enabled (i.e., included in the project file),  line 5276 would have access violation at address 0x00000001, and no log file will be archived.

If I removed FastMM5, then there won't be access violation, log files can be correctly archived.


I don't understand why FastMM5 would contribute to this, but guess I'll have to remove FastMM5?

#72 mORMot 1 » mormot.core.log - EventArchiveSynLZ bug? » 2021-09-17 00:34:36

wxinix
Replies: 9

EventArchiveSynLz ends up access violation at mormot.core.buffers, line 5276,
SetString(dst, nil, AlgoCompressDestLen(Head.UncompressedSize))

AlgoCompressDestLen appears to be an undefined abstract method.

#73 mORMot 1 » mormot.db.raw.sqlite3.static on Windows 64 » 2021-09-15 01:32:18

wxinix
Replies: 1

I have a project that references mormot.db.raw.sqlite.static.

Windows x64 build gave strange hints, complaining certain variables are declared but never used in 'mormot.db.raw.sqlite3.static' --- see below screen. 
Is this something that I should worry?

2021-09-14_21-26-18.png

#74 mORMot 1 » mORMot2 FormatUTF8 question » 2021-09-13 04:21:55

wxinix
Replies: 1

There are two versions of FormatUTF8, one is defined in mormot.core.text,  the other in mormot.core.json

Is this an intentional design?

#75 mORMot 1 » mORMot2 user interface generation for VCL » 2021-09-02 20:20:27

wxinix
Replies: 1

I found some interesting post long time ago, about automatic UI generation.   https://synopse.info/forum/viewtopic.php?id=280

Is this going to be (yet) supported by mORMot2?

#76 Re: mORMot 1 » mORMot2, TRestServerDB threadsafe? » 2021-08-27 11:26:35

ab wrote:

Of course, the whole REST framework is thread-safe.

Thank you very much.

Is it allowed to change SQL Model (e.g., adding more tables), and call VirtualTableExternalRegister again,  after TRestServerDB instance has been created?

For example:

FSQLModel := TSQLModel.Create([FTable1, FTable2]);
FServer := TRestServerDB.Create(FSQLModel, SQLITE_MEMORY_DATABASE_NAME, False, '');

Then, I need to add more tables FTable3, FTables4 to FSQLModel, LATER after FServer is created.  Can I used the following code?

FSQLModel.AddTable(FTable3);
FSQLModel.AddTable(FTable4);

#77 mORMot 1 » mORMot2, TRestServerDB threadsafe? » 2021-08-27 03:00:38

wxinix
Replies: 3

Is TRestServerDB threadsafe?

In one running process, there is an active TRestServerDB instance, which itself is a SQLite in memory server.

I'd like to access that same TRestServerDB instance from different threads.  Is that allowed?

#78 Re: mORMot 1 » mORMot2 ObjectLoadJSON question » 2021-08-25 20:29:37

Thank you very much @ab. 

It works!

#79 Re: mORMot 1 » mORMot2 ObjectLoadJSON question » 2021-08-25 15:33:27

@ab, many thanks for your feedback.

To explain things better, I created a project for you to replicate the issue I encountered.  You can download it from here

https://gist.github.com/wxinix/d9c41954 … 391f7b8aaa

#80 mORMot 1 » mORMot2 ObjectLoadJSON question » 2021-08-25 12:54:28

wxinix
Replies: 4

Given the following record definition:

TSegment = class(TSQLRecord)
strict private
  FID: Int64;
  FAttrs: Variant;
published
  property Attrs: Variant read FAttrs write FAttrs;
end;

And the following JSON string:

LJSON := '{ "RowID": 1, "Attrs": {"SegmentID": "1976-113", "From":"LEXINGTON AV/72 ST","To":"LEXINGTON AV/57 ST"} }' 

ObjectLoadJSON (LSegment, LJSON, nil,  [jpoHandleCustomVariants]) would return False, indicating invalid JSON format.  By debugging,  it shows that the parsing broke at "Attrs" - when the parser expects its value to be double quoted.

In other words, if the value of a Variant field is NOT DOUBLE QUOTED,  ObjectLoadJSON would fail.

Note:  ObjectLoadJSON had been working no problem with early mORMot2 (before June 2021).  I suspect some changes introduced to mormot.core.json changed the behavior of ObjectLoadJSON. 
Is this an intentional design, or a potential bug?

Thanks.

#81 mORMot 1 » Is SQLite 3.36 static lib already updated? » 2021-08-13 16:37:14

wxinix
Replies: 8

I downloaded from https://synopse.info/files/mormot2static.7z, today,

But it still seems to be the old 3.35 version.

#82 mORMot 1 » EventArchiveSynLZ would crash the program » 2021-06-15 22:45:49

wxinix
Replies: 1

This is a following up of this post https://synopse.info/forum/viewtopic.php?id=5887

It seems EventArchiveSynLZ would crash at mormot.core.buffers, Line 5073

  if {%H-}dst = '' then
            SetString(dst, nil, AlgoCompressDestLen(Head.UnCompressedSize));  //  CRASHHHHHHHH at this line

#83 Re: mORMot 1 » TSynLogPerThreadMode = ptIdentifiedInOnFile, 'File access denied'? » 2021-06-01 00:24:09

Thank you @ab and @flydev

It turns out the problem was caused by a StackOverFlow exception when the software was trying to sort an array in a background thread (spawned by OmniThread Lib).  I used EurekaLog (with multi-threading enabled) to figure that out.  So it is not mORMot2 or TSynLog problem.

But I do have a question - it seems that TSynLog cannot capture the StackOverFlow exception that happened in a background thread?

#84 Re: mORMot 1 » TSynLogPerThreadMode = ptIdentifiedInOnFile, 'File access denied'? » 2021-05-26 20:41:23

ab wrote:

I guess the first sentence is not finished.

Enable the logs and see where exactly the EIOERror is triggered.
I doubt it comes from TSynLog.

The whole story is here  https://en.delphipraxis.net/topic/5092- … violation/

Basically,  I had a multi-threaded application (mORMot2), which also uses TSynLog for logging purpose.  I have TSynLogPerThreadMode = ptIdentifiedInOnFile

Then,  the application after started, would run normal for a couple of hours, then it crashed.  By "a couple of hours" -  it is really random, sometimes it is 2~3 hours, sometimes more.

The crash is only logged by Windows Event Viewer, as Access Violation, with the fault offset.   TSynLog itself didn't log anything.  madExcept (if enabled) didn't log anything either.  FastMM5 (if enabled) didn't log anything, either.

From the fault offset, I can trace into somewhere in EIOError code.

If I turn off TSynLog completely,  then the access violation would be gone, and never happened.  Therefore, I suspect it is something related to TSynLog under multi-threaded environment. 

Right now, I had to turn of TSynLog and the application seems running all right without any problem.

#85 mORMot 1 » Will TSynLog work with MadExcept or EurekaLog? » 2021-05-25 23:55:11

wxinix
Replies: 1

If sllException is enabled,  will TSynLog conflict with MadExcept or EurekaLog, in terms of Exception reporting?

#86 mORMot 1 » TSynLogPerThreadMode = ptIdentifiedInOnFile, 'File access denied'? » 2021-05-25 21:58:32

wxinix
Replies: 6

How would TSynLog work, if TSynLogPerThreadMode = ptIdentifiedInOnFile, and

I am scratching my head, because I am occasionally having EIOError with "File access denied" problem.  By "occasionally" - I meant - the application (mORMot2 based)  will run normally for a couple of hours then it crashes with "File access defined" error.

Any advice?  This might not be mORMot2 problem but I am asking just in case folks here may share some insights.

#87 Re: mORMot 1 » Would multiple TRestServerDB instances in one Process allowed? » 2021-05-24 11:47:19

OK- it seems fine based on SQLite documentation:
https://www.sqlite.org/inmemorydb.html
"Opening two database connections each with the filename ":memory:" will create two independent in-memory databases."

#88 mORMot 1 » Would multiple TRestServerDB instances in one Process allowed? » 2021-05-24 11:19:46

wxinix
Replies: 2

Is it allowed to have multiple TRestServerDB instances in one Process?

The TRestServerDB instances are created using:

FServer := TRestServerDB.Create(FSQLModel, SQLITE_MEMORY_DATABASE_NAME, False, '');

#89 Re: mORMot 1 » mORMot2, strange performance pattern » 2021-05-22 21:07:34

ab wrote:

Before asking from abstract, enable the logs and check how many time take each step.
Perhaps the connection is recreated, or whatever.
I can't comment here. It could come from very diverse reasons. Also 6014*3 = 18,000 rows per seconds seems a pretty low number to me.

(and please don't put the logs here, but e.g. as an external gist, as asked by the forum rules)

I am pretty sure that the connection is not re-created.

This log snapshot shows that:  BatchAdd 6014 rows takes 2.14 s

https://www.dropbox.com/s/cnbqzmzpmtub6 … 5.png?dl=0

This log snapshot shows that: for the NEXT MINUTE,  BatchAdd 6014 rows takes 263.39ms

https://www.dropbox.com/s/ggfi5aqrpill4 … 9.png?dl=0

I don't understand why it has x10 speed difference, for the same number of rows.  Any heads up appreciated!

#90 mORMot 1 » mORMot2, strange performance pattern » 2021-05-22 19:58:31

wxinix
Replies: 2

mORMot2,  Zeos,  PostgresQL

Every ONE minute, the software (that uses mORMot2 as the ORM) will BATCH ADD a fixed number of 6014 rows.   Again,  This happens EVERY ONE minute.

I logged the time for each BATCH ADD operation.

I am perplexed by the pattern I observed - for every 5 consecutive BATCH ADD operations (that happened in 5 consecutive minutes), I saw the following  pattern repeated like below:

BatchAdd 6014 rows takes about 2 sec
BatchAdd 6014 rows takes about 300 ms
BatchAdd 6014 rows takes about 300 ms
BatchAdd 6014 rows takes about 300 ms
BatchAdd 6014 rows takes about 300 ms


In other words, every 5 minutes, the BatchAdd is slower to insert, then in between much faster.

What could cause this pattern?   Could this because I "misuse" mORMot, or some magic switch misplaced?

I'd expect EACH BatchAdd to have relatively similar time......

#92 Re: mORMot 1 » mORMot2, ObjectLoadJSON cannot load TDateTimeTS field » 2021-05-21 13:09:11

ab wrote:

TDateTimeTS ?
Where do you think the problem comes from?

Yes. I meant TDateTimeMS.

The problem of ObjectLoadJSON ended up in this part of code: mormot.core.rtti, LINE 3305-3309

function TRttiProp.SetValue(Instance: TObject; const Value: variant): boolean;
var
  k: TRttiKind;
  v64: Int64;
  f64: double;
  u: RawUtf8;
begin
  result := false; // invalid or unsupported type
  k := TypeInfo.Kind;
  if k in rkOrdinalTypes then
    if VariantToInt64(Value, v64) then
      SetInt64Value(Instance, v64)
    else
      exit
  else if k in rkStringTypes then
    if VarIsEmptyOrNull(Value) then // otherwise would set 'null' text
      SetAsString(Instance, '')
    else if VariantToUtf8(Value, u) then
      SetAsString(Instance, u)
    else
      exit
  else if k = rkFloat then
    if VariantToDouble(Value, f64) then   // <<--- the value is a DateTime string "2021-05-20T21:21:20.819", but the code is trying to convert it to a Double.
      SetFloatProp(Instance, f64)
    else
      exit
  else if k = rkVariant then
    SetVariantProp(Instance, Value)
  else
    exit;
  result := true;
end;

#93 mORMot 1 » mORMot2, ObjectLoadJSON cannot load TDateTimeTS field » 2021-05-21 01:27:44

wxinix
Replies: 4

ObjectLoadJSON cannot load a TDateTimeTS field, like the following (which was saved using ObjectToJSON).

{"ID":0,"CreateTime":"2021-05-20T21:21:20.819"}

Bug?

#94 Re: mORMot 1 » mORMot2, function EventArchiveSynLZ no longer available? » 2021-05-21 00:38:13

I am trying to look for EventArchiveSynLZ  in mORMot2, but it seems missing.  Is this purposeful?

#95 Re: mORMot 1 » mORMot and Spatial Database » 2021-05-20 12:33:04

ab wrote:

Also RTree are available at ORM level.

@ab
Thank you.  I am looking at spatialite  https://www.gaia-gis.it/fossil/libspatialite/index

Do you see any problem that using mORMot2 + spatialite (as SQLite extension)?  Advice?

#96 Re: mORMot 1 » AS_UNIQUE and woStoreStoredFalse design problem » 2021-05-18 21:09:46

I am suffering a similar/related issue (mORMot2).

To use ObjectTOJSON, I have to explicitly specify ObjectToJSON(myObject, [woStoreStoredFalse]), otherwise, the object won't be correctly serialized (i.e., those AS_UNIQUE fields will be missing).

#97 Re: mORMot 1 » mORMot and Spatial Database » 2021-05-17 22:35:31

mpv wrote:

PostGIS is a Postgres extension, so the same protocol is used between DB and clients, and on SynDB level it works

Thank you, but at ORM level, what data type should I use for Geometry type? Blob?

#98 mORMot 1 » mORMot and Spatial Database » 2021-05-17 20:25:37

wxinix
Replies: 5

May be this is an out-of-touch question:

can mORMot work with Spatial Database, like PostgreSQL/PostGIS?

#99 Re: mORMot 1 » Help! mORMot2 migration problem » 2021-05-16 13:14:20

OK.

I believe there is a bug of mORMot2

mormot.db.sql.zeos, line 694

    sTableName := meta.AddEscapeCharToWildcards(sTableName);  // <---- this line should be removed, because AddEscapeCharToWildcards is called TWICE!
    // do not escape https://synopse.info/forum/viewtopic.php?pid=34896#p34896
    res := meta.GetColumns('', sSchema,
      meta.AddEscapeCharToWildcards(sTableName), '');

#100 Re: mORMot 1 » Help! mORMot2 migration problem » 2021-05-16 12:11:02

I use Postgresql connection class.  It seems that mormot.db.sql.zeos, the following  method doesn't work properly?

 procedure TSqlDBZeosConnectionProperties.GetFields(const aTableName: RawUtf8;
  out Fields: TSqlDBColumnDefineDynArray);

Line 696

res := meta.GetColumns('', sSchema,
      meta.AddEscapeCharToWildcards(sTableName), '');

always returns EMPTY, thus the returned

out Fields: TSqlDBColumnDefineDynArray 

is always empty.  On the other hand,  however, from the backend PostgreSQL server log, I can see that the server is queried with correctly generated SQL, which indeed returned the list of fields.

Because returned Fields is always empty, CreateMissingTables will always try to recreate existing tables because of the empty Fields returned.

Is this a bug of mORMot2, or I am doing something wrong somewhere?

Board footer

Powered by FluxBB