question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Improve SQL performance

See original GitHub issue

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:

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
bpatrikcommented, 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

1reaction
desertwitchcommented, 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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How To Optimize SQL Queries Performance - Best Practices
What Are Some Best Practices for Optimizing SQL Query Performance? · Define Your Requirements · Reduce Table Size · Simplify Joins · Use...
Read more >
SQL Query Optimization: 12 Useful Performance Tuning Tips ...
12 Query optimization tips for better performance · Tip 1: Add missing indexes · Tip 2: Check for unused indexes · Tip 3:...
Read more >
Top 10 Tips Improve SQL Query Performance - Bigscal
Use Exists instead of Sub Query; Use Proper join instead of subqueries; Use “Where” instead of “Having” a clause; Apply index on necessary ......
Read more >
SQL Query Performance. 13 Tips on Improving Efficiencies
13 QUERY PERFORMANCE TIPS · 1. Owner/Schema Name · 2. The * Operator · 3. Nullable Columns · 4. Table Variables and Joins...
Read more >
Supercharge Your SQL Queries for Production Databases
1. Define business requirements first · Identify relevant stakeholders. Make sure all necessary parties are in the discussion to develop your query. ·...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found