Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve SQL performance #299

Open
bpatrik opened this issue May 13, 2021 · 5 comments
Open

Improve SQL performance #299

bpatrik opened this issue May 13, 2021 · 5 comments
Assignees

Comments

@bpatrik
Copy link
Owner

bpatrik commented May 13, 2021

Listing and searching is relatively slow currently, see: https://github.com/bpatrik/pigallery2/blob/master/benchmark/README.md.

Did some minimal local benchmarking and found that Issuing a SELECT * FROM media_entry takes <30ms from DB Browser from SQLite, while from code (even if I list raw results, not parsed JSON) it could take 300ms.
This is without getting all the relations (directory, faces, etc) and doing any where or sorting.

A more realistic query:

SELECT *,
 '[' || GROUP_CONCAT(  '{"name": "' || "person"."name" || '", "box": {"top":' || "faces"."boxTop" || ', "left":' || "faces"."boxLeft" || ', "height":' || "faces"."boxHeight" ||', "width":' || "faces"."boxWidth" || '}}'  ) ||']' as media_metadataFaces
FROM "media_entity" "media"
LEFT JOIN "face_region_entry" "faces" ON "faces"."mediaId"="media"."id" 
LEFT JOIN "person_entry" "person"ON "person"."id"="faces"."personId"
GROUP BY "media"."id"

In the DB app: 300ms, from nodejs: 7300ms (first run), 1000ms (following runs)
(The long faces concatenation select is there as I figured that returning with less rows has 30-40% better performance.)
I did the check on a DB with 21k photos, win 10, i7-6700HQ, with SSHD.

There is clearly some significant performance loss around typerom.

There is already some harsh thread about it on reddit: TypeORM Sucks!! Something I wanted to talk about since long!

Currently I see two alternatives:

  1. Using sqlite3 and mysql drivers directly
    • I do not prefer stepping to that path. Especially, as all queries would need to be written twice.
    • Maybe at some critical path, it would be possible to speed things up, although, not sure how typeorm would behave, If it got mixed with native queries.
  2. Looking for a typeorm alternative
    • Replacing typeorm would be a massive work as the majority of the backend code is about SQL selects and inserts.
      • The Inserting is particularly complicated.
    • I found mikro-orm as alternative, It has promising benchmark results: https://github.com/mikro-orm/benchmark

Blocking:

@desertwitch
Copy link
Contributor

Perhaps an option would be to use "better-sqlite3" in combination with TypeORM?
https://typeorm.io/#/connection-options/better-sqlite3-connection-options

better-sqlite3 seems to perform much faster than sqlite3 and in combination with TypeORM it seems to be simply a matter of switching out the npm package and TypeORM connection option from sqlite3 to better-sqlite3.

@desertwitch
Copy link
Contributor

desertwitch commented Nov 1, 2021

I have just tested the idea and it is simply a matter of switching out the existing sqlite3 dependency for better-sqlite3 (tested version 7.4.4). Since TypeORM is already compatible with better-sqlite3, you can then simply change the driver from type: 'sqlite' to type: 'better-sqlite3' in SQLConnection.ts (Line 195).

The positive performance impact is massive, especially on my database with ~150.000 images.

better-sqlite3 is compatible to any existing sqlite database files, so it should really be as simple as that.

On another note, I'd also update TypeORM itself to a more recent version, but I haven't tested whether a TypeORM update breaks anything yet.

@bpatrik
Copy link
Owner Author

bpatrik commented Nov 8, 2021

This sounds great!
I would need to spend some time with it to double check everything works and it indeed ads a speed up tho the app.

I already have some benchmark (that code is only best-effort maintained): https://github.com/bpatrik/pigallery2/tree/master/benchmark

I would need to run that to compare the benefit.

@bpatrik

This comment was marked as outdated.

@bpatrik
Copy link
Owner Author

bpatrik commented Feb 23, 2022

The previous benchmark result was corrupted so I had to rerun it.

There is a 10-12% increase with better-sqlite3 for every scenarios.

PiGallery2 v1.9.1, 23.02.2022

Version: v1.9.1, built at: Tue Feb 22 2022 23:16:30 GMT+0000 (Coordinated Universal Time), git commit:b4c64d12472bb618787168009eae103d59487ded
System: Raspberry Pi 4 4G Model B, SandisK Mobile Ultra 32Gb CLass10, UHS-I, HDD: Western Digital Elements 1TB (WDBUZG0010BBK)

Gallery: directories: 31, photos: 2036, videos: 35, diskUsage : 22.08GB, persons : 1381, unique persons (faces): 25

Action Sub action Average Duration Result
Scanning directory 10184.3 ms media: 698, directories: 0
[SQlite=better-sqlite]Scanning directory 10177.5 ms media: 698, directories: 0
Saving directory to DB 4095.6 ms -
[SQlite=better-sqlite]Saving directory to DB 1963.8 ms -
List directory 411.9 ms media: 698, directories: 0
Authenticate 0.1 ms -
Normalize path param 0.0 ms -
Authorise path 0.0 ms -
Inject gallery version 3.9 ms -
List directory 328.3 ms media: 698, directories: 0
Add thumbnail information 58.8 ms media: 698, directories: 0
Clean up gallery results 20.5 ms media: 698, directories: 0
Render result 0.0 ms media: 698, directories: 0
[SQlite=better-sqlite]List directory 326.5 ms media: 698, directories: 0
Authenticate 0.1 ms -
Normalize path param 0.0 ms -
Authorise path 0.0 ms -
Inject gallery version 2.7 ms -
List directory 248.1 ms media: 698, directories: 0
Add thumbnail information 57.1 ms media: 698, directories: 0
Clean up gallery results 18.1 ms media: 698, directories: 0
Render result 0.0 ms media: 698, directories: 0
Listing Faces 43.5 ms items: 25
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 3.4 ms -
List persons 36.5 ms items: 25
Add thumbnail info for persons 1.6 ms items: 25
Clean up person results 1.7 ms items: 25
Render result 0.0 ms items: 25
[SQlite=better-sqlite]Listing Faces 38.6 ms items: 25
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 2.4 ms -
List persons 31.1 ms items: 25
Add thumbnail info for persons 2.3 ms items: 25
Clean up person results 2.5 ms items: 25
Render result 0.0 ms items: 25
Searching for a 937.2 ms media: 2001, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 716.2 ms media: 2001, directories: 0
Add thumbnail information 171.1 ms media: 2001, directories: 0
Clean up gallery results 49.3 ms media: 2001, directories: 0
Render result 0.0 ms media: 2001, directories: 0
[SQlite=better-sqlite]Searching for a 818.5 ms media: 2001, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 604.7 ms media: 2001, directories: 0
Add thumbnail information 165.0 ms media: 2001, directories: 0
Clean up gallery results 48.2 ms media: 2001, directories: 0
Render result 0.0 ms media: 2001, directories: 0
Searching for caption:a 10.8 ms media: 0, directories: 0
Authenticate 0.0 ms -
Authorise 0.0 ms -
Inject gallery version 0.1 ms -
Search 10.4 ms media: 0, directories: 0
Add thumbnail information 0.1 ms media: 0, directories: 0
Clean up gallery results 0.0 ms media: 0, directories: 0
Render result 0.0 ms media: 0, directories: 0
[SQlite=better-sqlite]Searching for caption:a 9.5 ms media: 0, directories: 0
Authenticate 0.0 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 9.0 ms media: 0, directories: 0
Add thumbnail information 0.1 ms media: 0, directories: 0
Clean up gallery results 0.0 ms media: 0, directories: 0
Render result 0.0 ms media: 0, directories: 0
Searching for directory:a 803.2 ms media: 1705, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 610.4 ms media: 1705, directories: 0
Add thumbnail information 151.6 ms media: 1705, directories: 0
Clean up gallery results 40.6 ms media: 1705, directories: 0
Render result 0.0 ms media: 1705, directories: 0
[SQlite=better-sqlite]Searching for directory:a 689.0 ms media: 1705, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 502.3 ms media: 1705, directories: 0
Add thumbnail information 145.9 ms media: 1705, directories: 0
Clean up gallery results 40.2 ms media: 1705, directories: 0
Render result 0.0 ms media: 1705, directories: 0
Searching for file-name:a 47.0 ms media: 79, directories: 0
Authenticate 0.0 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 38.4 ms media: 79, directories: 0
Add thumbnail information 6.3 ms media: 79, directories: 0
Clean up gallery results 1.9 ms media: 79, directories: 0
Render result 0.0 ms media: 79, directories: 0
[SQlite=better-sqlite]Searching for file-name:a 43.6 ms media: 79, directories: 0
Authenticate 0.0 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 33.9 ms media: 79, directories: 0
Add thumbnail information 7.3 ms media: 79, directories: 0
Clean up gallery results 2.0 ms media: 79, directories: 0
Render result 0.0 ms media: 79, directories: 0
Searching for keyword:a 723.3 ms media: 1536, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 548.7 ms media: 1536, directories: 0
Add thumbnail information 137.8 ms media: 1536, directories: 0
Clean up gallery results 36.2 ms media: 1536, directories: 0
Render result 0.0 ms media: 1536, directories: 0
[SQlite=better-sqlite]Searching for keyword:a 622.2 ms media: 1536, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 455.3 ms media: 1536, directories: 0
Add thumbnail information 131.9 ms media: 1536, directories: 0
Clean up gallery results 34.5 ms media: 1536, directories: 0
Render result 0.0 ms media: 1536, directories: 0
Searching for person:a 409.4 ms media: 825, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 315.9 ms media: 825, directories: 0
Add thumbnail information 71.7 ms media: 825, directories: 0
Clean up gallery results 21.3 ms media: 825, directories: 0
Render result 0.0 ms media: 825, directories: 0
[SQlite=better-sqlite]Searching for person:a 355.6 ms media: 825, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 266.1 ms media: 825, directories: 0
Add thumbnail information 67.8 ms media: 825, directories: 0
Clean up gallery results 21.1 ms media: 825, directories: 0
Render result 0.0 ms media: 825, directories: 0
Searching for position:a 547.7 ms media: 1133, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 419.1 ms media: 1133, directories: 0
Add thumbnail information 96.5 ms media: 1133, directories: 0
Clean up gallery results 31.6 ms media: 1133, directories: 0
Render result 0.0 ms media: 1133, directories: 0
[SQlite=better-sqlite]Searching for position:a 486.1 ms media: 1133, directories: 0
Authenticate 0.0 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 365.4 ms media: 1133, directories: 0
Add thumbnail information 93.8 ms media: 1133, directories: 0
Clean up gallery results 26.4 ms media: 1133, directories: 0
Render result 0.0 ms media: 1133, directories: 0
Searching for . 955.6 ms media: 2001, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 732.7 ms media: 2001, directories: 0
Add thumbnail information 174.5 ms media: 2001, directories: 0
Clean up gallery results 47.8 ms media: 2001, directories: 0
Render result 0.0 ms media: 2001, directories: 0
[SQlite=better-sqlite]Searching for . 809.4 ms media: 2001, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.5 ms -
Search 598.4 ms media: 2001, directories: 0
Add thumbnail information 162.8 ms media: 2001, directories: 0
Clean up gallery results 47.3 ms media: 2001, directories: 0
Render result 0.0 ms media: 2001, directories: 0
Searching for <Most common name> 156.5 ms media: 262, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 122.7 ms media: 262, directories: 0
Add thumbnail information 23.8 ms media: 262, directories: 0
Clean up gallery results 9.5 ms media: 262, directories: 0
Render result 0.0 ms media: 262, directories: 0
[SQlite=better-sqlite]Searching for <Most common name> 122.5 ms media: 262, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 92.5 ms media: 262, directories: 0
Add thumbnail information 22.6 ms media: 262, directories: 0
Clean up gallery results 7.0 ms media: 262, directories: 0
Render result 0.0 ms media: 262, directories: 0
Searching for <Most AND second common names> 28.9 ms media: 20, directories: 0
Authenticate 0.0 ms -
Authorise 0.0 ms -
Inject gallery version 0.1 ms -
Search 26.2 ms media: 20, directories: 0
Add thumbnail information 1.7 ms media: 20, directories: 0
Clean up gallery results 0.6 ms media: 20, directories: 0
Render result 0.0 ms media: 20, directories: 0
[SQlite=better-sqlite]Searching for <Most AND second common names> 27.4 ms media: 20, directories: 0
Authenticate 0.0 ms -
Authorise 0.0 ms -
Inject gallery version 0.1 ms -
Search 24.5 ms media: 20, directories: 0
Add thumbnail information 1.8 ms media: 20, directories: 0
Clean up gallery results 0.7 ms media: 20, directories: 0
Render result 0.0 ms media: 20, directories: 0
Searching for <Most OR second common names> 236.0 ms media: 448, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 187.7 ms media: 448, directories: 0
Add thumbnail information 36.0 ms media: 448, directories: 0
Clean up gallery results 11.6 ms media: 448, directories: 0
Render result 0.1 ms media: 448, directories: 0
[SQlite=better-sqlite]Searching for <Most OR second common names> 210.5 ms media: 448, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 159.8 ms media: 448, directories: 0
Add thumbnail information 38.1 ms media: 448, directories: 0
Clean up gallery results 12.1 ms media: 448, directories: 0
Render result 0.0 ms media: 448, directories: 0
Searching for <Contain at least 2 out of all names> 461.2 ms media: 323, directories: 0
Authenticate 0.0 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 421.6 ms media: 323, directories: 0
Add thumbnail information 27.5 ms media: 323, directories: 0
Clean up gallery results 11.6 ms media: 323, directories: 0
Render result 0.0 ms media: 323, directories: 0
[SQlite=better-sqlite]Searching for <Contain at least 2 out of all names> 382.0 ms media: 323, directories: 0
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Search 344.4 ms media: 323, directories: 0
Add thumbnail information 27.7 ms media: 323, directories: 0
Clean up gallery results 9.4 ms media: 323, directories: 0
Render result 0.0 ms media: 323, directories: 0
Auto complete for a 19.3 ms items: 24
Authenticate 0.1 ms -
Authorise 0.0 ms -
Inject gallery version 0.2 ms -
Autocomplete 18.9 ms items: 24
Render result 0.0 ms items: 24
[SQlite=better-sqlite]Auto complete for a 13.5 ms items: 24
Authenticate 0.0 ms -
Authorise 0.0 ms -
Inject gallery version 0.1 ms -
Autocomplete 13.2 ms items: 24
Render result 0.0 ms items: 24
*Measurements run 20 times and an average was calculated.

run for : 2696203.0ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants