Jump to content

Search Very Slow (3 minute response)


Recommended Posts

kingom
Posted
On 7/26/2026 at 7:17 PM, Luke said:

The browser also has added cancellation of the previous search when you add another letter, and now this cancellation makes it all the way up to the database query. This helps a lot.

 But not all apps can do that and some of the ones that can haven’t gotten a store update with it yet:

In the past, search was working with the LG App.
Problems started when updating the Server to 4.9.1.90

  • Agree 1
Rumzzz
Posted

New beta dropped with search improvements!! Will vigorously test soon 🙏

 

  • Haha 1
bandit8623
Posted
22 minutes ago, Rumzzz said:

New beta dropped with search improvements!! Will vigorously test soon 🙏

 

vigorous searches!!

Chillout
Posted (edited)

With .21 beta still experiencing long searches that make the server unresponsive.

searching: star wars    - results are immediate

searching for: war  -spinning circle for minutes causing server to lag

I dont mind searches that take long, I don't  like how one user can cause problems for everyone else.

 

 

Edited by Chillout
  • Agree 2
Rumzzz
Posted (edited)

@Chilloutare you on 4.10.0.21?

I'm also still running into server locking searches (both single and multi word) for a handful of my tests, although it seems less often than before. 

Certain searches that block the server will eventually bring back results if I wait long enough or try enough times. Once results return for a problematic search phrase, subsequent searches for the same phrase seen to return more reliably (cached?).

I think we have 2 different issues people are reporting here:

1) Search queries aren't efficient / take too long

2) Querying the database causes all sessions to lock up

Edited by Rumzzz
  • Agree 2
Posted

How does 4.10.0.22 compare?

Chillout
Posted

I dont notice much change.... .some 22 searches still lock up the server for other users.

searching for:  black mirror  -near instant results

searching for: black   -locks things up for  ~60sec until it shows results

 

Rumzzz
Posted (edited)

I appreciate the recent work on this.

In my initial testing of 22 I do feel a moderate improvement, but still a handful of searches (mostly small/common words) will timeout, and will hold up the server while searching (although the timeout limit seems to be reduced, leading to less time blocking the server for others).

I do like the recently searched section though! Not sure when that was added, but it does seem to have a few issues I can post in a different thread. The loading of this list alone takes almost 15 seconds for me, so that kinda seems like it might add to the timeouts if a search happens before this list loads.

I'm still continuing to test and collect feedback from my other users.

Edited by Rumzzz
  • Thanks 2
Napsterbater
Posted

Web UI seems ok on .22, from Android App still seems to lock up the server for others.

  • Thanks 1
blinky
Posted

I ended up installing the stable 4.9.50 version and searching works as expected now, no lockups at all so I'll be sticking to it for now

 

Also my hardware is 

AMD ryzen 5 5600x with 16gb ram running windows 11 pro, and about 84tb of storage which most of the drives are full, I need more storage soon 😭😭 so expensive atm

  • Agree 2
crash1015
Posted
On 8/2/2026 at 4:35 PM, blinky said:

I ended up installing the stable 4.9.50 version and searching works as expected now, no lockups at all so I'll be sticking to it for now

 

Also my hardware is 

AMD ryzen 5 5600x with 16gb ram running windows 11 pro, and about 84tb of storage which most of the drives are full, I need more storage soon 😭😭 so expensive atm

So does this mean I need to reinstall? I'm using 4.9.50 and I'm still having issues. I just don't want to reinstall unless it's certainly going to fix it. 

crash1015
Posted
14 hours ago, Rumzzz said:

Looking at the release notes on git, looks like 4.9.1.80 was the introduction of the fuzzy-search changes (Improve results of multi-word searches), so I'm assuming any version previous to this one will not have the issue.

https://github.com/MediaBrowser/Emby.Releases/releases#release-4.9.1.80

Downgrading from what i have now sounds like a daunting task. Won't the database have issues?

  • Agree 1
Rumzzz
Posted
1 hour ago, crash1015 said:

Downgrading from what i have now sounds like a daunting task. Won't the database have issues?

Yes, which is exactly what's preventing myself from downgrading, because the database changes typically require a clean install. 

You can try a dirty install of an older version (after you've backup up your system folder), but do so at your own risk with no guarantees.

  • Agree 1
  • Thanks 1
Rumzzz
Posted (edited)

New beta 4.10.0.23 seems promising! Did a quick handful of searches and so far they all came back within ~15 seconds, some near instantly!

I've got much more in-depth testing I will do later, but would love to hear from others.

Edited by Rumzzz
  • Thanks 3
Rumzzz
Posted

Ok so after some more testing I did run into a few queries that timed out, again mostly smaller/more common words, but it's MUCH less often than before. The small amount of timed out queries I ran into eventually worked if I retried them.

Not sure if the recently searched list is affecting this, but it does take a while for that list to load, and will sometimes time out or will load after my search query.

Still seems like the Emby process doesn't use as many threads/cores as is available on my 13600k when searching. The server does still seem to ramp up my fans and  lock up during longer searches, though the amount of time it's locked has lessened noticably.

I know how hard it can be fixing efficiencies when different users report different things, so thank you for the continued work on this. Looking forward to hearing from other users running on different hardware/platforms.

  • Like 1
  • Thanks 2
Napsterbater
Posted

4.10.0.23 still has issues from Android clients for me, same symptoms as before.

Chillout
Posted

.23 beta seems to have fixed the slow search for safari, web, and windows app so I am happy.  TY devs.

 

 

  • Like 1
  • Thanks 1
Napsterbater
Posted
On 8/10/2026 at 4:15 AM, Napsterbater said:

4.10.0.23 still has issues from Android clients for me, same symptoms as before.

The same exact search results in WebUI work, yet word for word in the Android App locks up the server for minutes.

  • Thanks 1
Rumzzz
Posted

I think the search is massively improved however there are still occasionally a few search queries that timeout.

I think an important part of this problem is how the server locks up during search. Even with the vast majority of successful searches, it's still 15-20 seconds of server downtime anytime a user does a search (I can't even get the dashboard to load).

Is that something we can have looked into? Should that merit its own discussion thread?

  • Agree 1
Napsterbater
Posted
9 minutes ago, Rumzzz said:

I think the search is massively improved however there are still occasionally a few search queries that timeout.

I think an important part of this problem is how the server locks up during search. Even with the vast majority of successful searches, it's still 15-20 seconds of server downtime anytime a user does a search (I can't even get the dashboard to load).

Is that something we can have looked into? Should that merit its own discussion thread?

In my experience with the Android app searching, it is far longer than 15-20 seconds, it can be up to like 3 minutes +/-, however, as I said before, same search terms work perfectly fine on web UI, and I don't use search a lot especially from the web UI because I'm mainly using Android clients, So I don't know if there's some magic combination that would cause it to happen on the web UI as well, and if it does happen, is it the same 3 minutes, or is it shorter.

 

Posted

Have the same issue here since a while - it is not only on searching with explicit names.

Just have yout CD collection and try from master directory a random play.

Causes my PC the wait a long time - sometimes it will playx, sometimes not.

Database needs a speed up - on bigger amount of entries it will downgrade in speed now.

A suggestion would be a kind of vaccumisation (as with postgres) or switching to mariaDB - both can handle a bigger amount of data.

But this is a design decision ....

regards,

Rüdiger

Posted
29 minutes ago, ruedi said:

Have the same issue here since a while - it is not only on searching with explicit names.

Just have yout CD collection and try from master directory a random play.

Causes my PC the wait a long time - sometimes it will playx, sometimes not.

Database needs a speed up - on bigger amount of entries it will downgrade in speed now.

A suggestion would be a kind of vaccumisation (as with postgres) or switching to mariaDB - both can handle a bigger amount of data.

But this is a design decision ....

regards,

Rüdiger

Let me add some things ... 

OS running: Debian 13, completely patched as virtual client under Proxmox

Emby-Version: 4.10.0.27

Saw now a different behavior, potentially we have a second porblem ;)

Using the App under Windows 11: search process to create the file list is running, host = 100% load. After a while CPU load is decreasing to 4% -> Windows App is not playing (circle is turning, Mous operations are possibl, no sound)

 

Using the Web-App with Firefox under Windows 11: search process to create the file list is running, host = 100% load. After a while CPU load is decreasing to 4% -> Sound is playing

 

So it seems, there is a communication problem to the app, to.

 

And ... yes, there is an option to enable "vacuumisation" on the DB, but only on next start of server, which can take months. Possibly we need this to do more often as a subtak - possibly at night. A bit strange.... my library.db is 939474944 Bytes, after restart with vacuumisation it stay the same, but library.db-wal has the same size. I did not expect this ..

regards,

Rüdiger

 

 

  • Thanks 1
flord22
Posted

Got a bit tired of waiting so I let Claude try to do a fix for this and it did it. Search is close to instant on anything I try now. There were 2 issues it fixed. Each issue is explained in its own post one after another here then a guide how to apply it and how to revert it. in case if emby team ever fixes it in their update so you can re run their update afterwards. 

4.10.x: "Recent searches" query (WasSearched/DateLastSearched) freezes entire server for 1–2 minutes on large libraries

Versions affected (observed): 4.10.0.20, 4.10.0.23, 4.10.0.25 (Linux/Ubuntu 24.04, .NET 8.0.28, bundled SQLite 3.53.3). Did not occur on 4.9.x. Library size: ~191,000 MediaItems, ~555,000 UserDatas rows.

Symptom

Opening the search page in Emby Web fires GET /Users/{id}/Items?SortBy=DateLastSearched,SortName&SortOrder=Descending&Limit=20&Recursive=true&EnableTotalRecordCount=false&WasSearched=true (the "recent searches" panel — fired before the user types anything). On our server this single query runs 87–117 seconds of pure CPU inside sqlite3_step() (one thread pinned at 100%, zero disk I/O, verified with gdb + strace). While it runs, effectively the whole server convoys behind it: complex item queries and user-data writes queue (/Sessions/Playing/Progress POSTs took 89–99s; requests observed starved up to 15 minutes across consecutive episodes), then everything flushes in the same second the query completes. To all users the server appears completely hung.

Typed search itself is NOT the culprit on our server: the FTS-based SearchTerm queries measure 27–850ms standalone (they only appeared slow because they queued behind the recent-searches query). This is likely the same class of issue reported in "Search Very Slow (3 minute response)" (topic 144128).

Root cause (verified)

The SQL (recovered verbatim from a process core dump taken mid-freeze; abbreviated):

select ..., (Select ShareLevel from UserItemShares join AncestorIds2
             on AncestorIds2.AncestorId=UserItemShares.ItemId
             where UserItemShares.UserId=1 and UserItemShares.ShareLevel not null
               and AncestorIds2.ItemId=A.Id order by Distance limit 1) as ShareLevel
from mediaitems A
left join UserDatas on A.UserDataKeyId=UserDatas.UserDataKeyId And UserDatas.UserId=1
where A.Type in (1,2,5,6,8,...,34)
  AND UserDatas.DateLastSearchedInt > 0
  AND (ShareLevel > 0 OR A.Type in (...) OR A.IsPublic=1)
  AND A.ExtraType is null
  AND ( EXISTS (SELECT 1 FROM AncestorIds2 WHERE itemid=A.Id AND AncestorId in (...))
     OR EXISTS (ListItems join ancestorids2 ...)
     OR EXISTS (itemPeople2 JOIN AncestorIds2 ...)
     OR EXISTS (ItemLinks2 join ancestorids2 ... Type in (...))
     OR EXISTS (ItemLinks2 ItemLinks2TwoLevel WHERE EXISTS (...) ...) )
Group by A.PresentationUniqueKey
ORDER BY MAX(UserDatas.DateLastSearchedInt) DESC NULLS LAST,
         A.SortName collate NATURALSORT DESC LIMIT 20

There is no index on UserDatas.DateLastSearchedInt, so the planner cannot see that DateLastSearchedInt > 0 is extremely selective (only ~10–100 rows in the whole table ever have it set). SQLite then picks this plan (EXPLAIN QUERY PLAN from a copy of the production DB):

SEARCH A USING INDEX idx_MediaItems47cd2 (type=? AND ExtraType=?)   -- ~176k rows
  CORRELATED SCALAR SUBQUERY 1 (ShareLevel)  -- incl. USE TEMP B-TREE FOR ORDER BY, per row!
  CORRELATED SCALAR SUBQUERIES 2..7 (the visibility EXISTS chain, per row)
SEARCH UserDatas USING INDEX UserDatasIndexUnique1 (UserDataKeyId=? AND userId=?)  -- applied LAST

i.e. it scans ~176k items and evaluates the ShareLevel subquery (with a per-row sort) plus up to five correlated visibility subqueries for every row, and only then joins UserDatas where DateLastSearchedInt > 0 throws away all but ~10 rows. Measured: >90 s. The mirror plan (drive from UserDatas first) takes ~2 s; which plan a pooled connection gets appears to depend on the sqlite_stat1 state at prepare time, which is why the freeze is intermittent and per-connection ("plan roulette" — we observed the identical request take 116,798 ms and, four minutes later, 2,351 ms). ANALYZE does NOT stabilize the good plan (after a fresh ANALYZE the planner chose SCAN A, still >60 s).

Fix that works (verified on production)

CREATE INDEX idx_UserDatas_LastSearched
ON UserDatas(UserId, DateLastSearchedInt)
WHERE DateLastSearchedInt IS NOT NULL;

Build time 0.2 s (partial index over the handful of rows that have the column set). The planner then drives from this index in every stats state we tested. Result on the live server: the recent-searches request went from 116,798 ms → 16 ms, and the server-wide freezes stopped. Suggest shipping this index (or equivalent) in the 4.10 schema, and/or restructuring the query so the selective DateLastSearchedInt predicate drives the join rather than being applied after the per-row ShareLevel/visibility subqueries.

Notes

  • No SQLite errors of any kind in logs (no "database is locked", no corruption); PRAGMA quick_check ok. The DB stays fully readable by other processes during the freeze (external probe queries answered in 34–52 ms throughout) — the hang is entirely this query plus the connection-pool convoy behind it.

  • Reproduction needs: a multi-user library in the 100k+ item range, at least one user with DateLastSearchedInt set (i.e. someone has used search before), and folder-restricted users (the ShareLevel/visibility subqueries).

  • Secondary observation: Debug App: Sqlite: 284 - automatic index on ... warnings appear frequently for LastWatchedEpisodes(SeriesPresentationUniqueKey) and LinkedCounts(AId) (materialized subqueries in the NextUp/Resume queries) — worth a look for the same reason, but not the freeze trigger here.

  • Thanks 3
flord22
Posted (edited)

Edit: This is the 3rd post explaining how to do and revert the patches. The 2nd post (the one explaining the 2nd fix) got limited or something and is hidden until mods or someone approves it.

Emby 4.10.x search-freeze workarounds — how to apply and revert each patch

These are the workarounds referenced in my two bug reports (the "recent searches query freezes the server" thread and the "SearchTerm slowness / degenerate planner statistics" thread). They fixed, on our server (~191,000-item library):

  • the whole server freezing for 1–2 minutes whenever someone opened search (100+ s → 16 ms),

  • searches like lord taking a flat ~13 s (→ under 1 s),

  • 1–2-letter searches from TV apps (which search per keystroke) taking 30–50 s and stalling everyone else (→ under 0.3 s).

Read before starting

  • At your own risk. These modify the live Emby database (an index and planner statistics) and system.xml. They are workarounds until the Emby team fixes this properly. Make the backups in Step 0 first.

  • Applies to the 4.10.x beta schema (tables MediaItems, UserDatas, AncestorIds2). If those tables don't exist in your library.db, you're on 4.9.x or older — this guide does not apply.

  • Paths below are for the Linux .deb install (/var/lib/emby). Docker: run the commands where the config volume is mounted. Windows: the same SQL applies via any SQLite tool against library.db in your programdata folder.

  • Commands use python3 (preinstalled on most Linux servers) so you don't need the sqlite3 CLI. If you have the CLI, the SQL statements inside work there too.

  • Run as root.

  • "Cookie poke": SQLite only re-plans cached queries when the schema version changes. ANALYZE and statistics edits don't change it, so after Patches 2/4 the running server keeps its old (slow) query plans until you either restart Emby or "poke" the schema version by creating and dropping a dummy index. The poke is included in the commands below. Patch 1 (real DDL) needs no poke.

  • Never edit system.xml while Emby is running — Emby rewrites it from memory on shutdown and your edit is silently lost. Always stop → edit → start.

# Patch Fixes

Downtime

0 Backups none
1 Partial index on UserDatas Search page freezing
the whole server
none
2 Full ANALYZE Flat ~13 s searches
(bad statistics)
none
3 system.xml settings Flat ~13 s searches
(bad statistics)
~1 min restart
4 Statistics override for AncestorIds2 Stops Emby re-creating
the bad statistics;
bigger DB pool
none
       
       
       
       
       
       

Step 0 — Backups (do this first)

Consistent snapshot of the live database (safe while Emby runs, uses SQLite's VACUUM INTO😞

mkdir -p /root/emby-backups
python3 -c "
import sqlite3, time
con = sqlite3.connect('file:/var/lib/emby/data/library.db?mode=ro', uri=True, timeout=60)
dest = '/root/emby-backups/library-backup-' + time.strftime('%Y%m%d') + '.db'
con.execute(\"VACUUM INTO '\" + dest + \"'\")
con.close(); print('backup written:', dest)"

Copy of the config file:

cp /var/lib/emby/config/system.xml /root/emby-backups/system.xml.bak-$(date +%Y%m%d)

Snapshot of the current planner statistics (lets you revert Patch 2/4 exactly):

python3 -c "
import sqlite3, time
con = sqlite3.connect('file:/var/lib/emby/data/library.db?mode=ro', uri=True)
rows = con.execute('SELECT tbl, idx, stat FROM sqlite_stat1').fetchall()
dest = '/root/emby-backups/sqlite_stat1-backup-' + time.strftime('%Y%m%d') + '.sql'
with open(dest,'w') as f:
    f.write('DELETE FROM sqlite_stat1;\n')
    for t,i,s in rows:
        f.write(f'INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES({t!r},{i!r},{s!r});\n')
print('stats snapshot written:', dest)"

Patch 1 — Partial index for the "recent searches" query

Problem it fixes: opening the search page fires Items?...WasSearched=true&SortBy=DateLastSearched before you even type. There is no index on UserDatas.DateLastSearchedInt, and the planner can pick a plan that scans your whole library with expensive per-row visibility subqueries — 100+ seconds of CPU during which everything else on the server queues. This tiny partial index (it only covers the handful of rows where the column is set) makes the plan trivially correct in every case.

Apply (safe while Emby runs, ~0.2 s, takes effect immediately):

python3 -c "
import sqlite3
con = sqlite3.connect('/var/lib/emby/data/library.db', timeout=60)
con.execute('PRAGMA busy_timeout=60000')
con.execute('CREATE INDEX IF NOT EXISTS idx_custom_UserDatas_LastSearched ON UserDatas(UserId, DateLastSearchedInt) WHERE DateLastSearchedInt IS NOT NULL')
con.commit(); con.close(); print('index created')"

Revert:

python3 -c "
import sqlite3
con = sqlite3.connect('/var/lib/emby/data/library.db', timeout=60)
con.execute('PRAGMA busy_timeout=60000')
con.execute('DROP INDEX IF EXISTS idx_custom_UserDatas_LastSearched')
con.commit(); con.close(); print('index dropped')"

Verify: open search in Emby Web, then check the request time in the server log — should be milliseconds:

grep 'WasSearched=true' /var/lib/emby/logs/embyserver.txt | grep -oE 'Time: [0-9]+ms' | tail -5

Survives restarts, server updates, and VACUUM. Emby doesn't know about it; drop it once an official fix ships.


Patch 2 — Full ANALYZE (fix the planner statistics)

Problem it fixes: Emby's default DatabaseAnalysisLimit=5000 makes its maintenance run a sampled ANALYZE. On the heavily skewed AncestorIds2 table (folder hierarchy) the sample produces wildly wrong statistics ("1 row per folder" when big folders have tens of thousands), and the planner then picks catastrophic plans for search queries. A full, unlimited ANALYZE records correct statistics.

Apply (safe while Emby runs, ~1–2 s, poke included):

python3 -c "
import sqlite3
con = sqlite3.connect('/var/lib/emby/data/library.db', timeout=60)
con.execute('PRAGMA busy_timeout=60000')
con.execute('ANALYZE'); con.commit()
con.execute('CREATE INDEX IF NOT EXISTS idx_custom_statspoke ON ItemExtradataTypes(Name)'); con.commit()
con.execute('DROP INDEX IF EXISTS idx_custom_statspoke'); con.commit()
con.close(); print('ANALYZE done + plans refreshed')"

Note: running plain ANALYZE also erases Patch 4 if you applied it — the combined recipe at the end reapplies both in one go.

Revert (restore the statistics snapshot from Step 0 — only useful for debugging):

python3 -c "
import sqlite3, glob
con = sqlite3.connect('/var/lib/emby/data/library.db', timeout=60)
con.execute('PRAGMA busy_timeout=60000')
snap = sorted(glob.glob('/root/emby-backups/sqlite_stat1-backup-*.sql'))[-1]
con.executescript(open(snap).read()); con.commit()
con.execute('CREATE INDEX IF NOT EXISTS idx_custom_statspoke ON ItemExtradataTypes(Name)'); con.commit()
con.execute('DROP INDEX IF EXISTS idx_custom_statspoke'); con.commit()
con.close(); print('restored', snap)"

Patch 3 — system.xml settings

Problems these fix: the first two stop Emby's own maintenance from re-creating the bad statistics (undoing Patches 2 and 4 at every shutdown); the pool increase keeps writes (playback progress reporting) flowing when heavy queries are running. Note: a bigger pool alone does NOT stop search convoys — Emby serializes list-type queries internally — which is why Patch 4 matters.

In /var/lib/emby/config/system.xml change:

<DatabaseAnalysisLimit>0</DatabaseAnalysisLimit>            <!-- was 5000 -->
<OptimizeDatabaseOnShutdown>false</OptimizeDatabaseOnShutdown>  <!-- was true -->
<MaxLibraryDatabaseConnections>10</MaxLibraryDatabaseConnections>  <!-- was 5; ~your CPU core count is a reasonable value -->

Apply (stop → edit → start; ~1 min downtime, streams drop and auto-resume):

systemctl stop emby-server
nano /var/lib/emby/config/system.xml
systemctl start emby-server

Revert: same procedure with the original values (see your Step 0 backup of the file; prefer editing values individually over copying the whole file back, in case you changed other settings via the dashboard since).

Verify the pool size after start:

grep 'SqliteItemRepository: Initializing PooledDatabaseConnectionManager' /var/lib/emby/logs/embyserver.txt | tail -1

Re-check these values after Emby package updates.


Patch 4 — Statistics override for AncestorIds2 (the TV-search fix)

Problem it fixes: even correct statistics only store the average rows-per-folder (a few), while the top-level library folders used in per-user visibility checks hold thousands to tens of thousands of items. SQLite (without STAT4, which Emby's build lacks) can't see the skew, so inside the per-row visibility subqueries it still drives from the folder side. Every search pays ~1–10 ms per matched item — 1–2-letter searches from TV apps (thousands of matches) take 30–50 s and stall other list queries. This override deliberately overstates the folder-side cost so the planner always probes from the item side instead.

The first number in the stat is your table's row count, so it's computed dynamically:

Apply (safe while Emby runs, instant, poke included):

python3 -c "
import sqlite3
con = sqlite3.connect('/var/lib/emby/data/library.db', timeout=60)
con.execute('PRAGMA busy_timeout=60000')
n = con.execute('SELECT COUNT(*) FROM AncestorIds2').fetchone()[0]
con.execute('UPDATE sqlite_stat1 SET stat=? WHERE tbl=? AND idx=?', (f'{n} 3000 1','AncestorIds2','idxAncestorIds2_1'))
con.commit()
con.execute('CREATE INDEX IF NOT EXISTS idx_custom_statspoke ON ItemExtradataTypes(Name)'); con.commit()
con.execute('DROP INDEX IF EXISTS idx_custom_statspoke'); con.commit()
con.close(); print(f'override applied: {n} 3000 1')"

(3000 approximates the real descendant count of large library folders; the exact value isn't critical — it just needs to be much larger than the item side's few rows.)

Revert (a plain full ANALYZE restores honest measured statistics):

python3 -c "
import sqlite3
con = sqlite3.connect('/var/lib/emby/data/library.db', timeout=60)
con.execute('PRAGMA busy_timeout=60000')
con.execute('ANALYZE'); con.commit()
con.execute('CREATE INDEX IF NOT EXISTS idx_custom_statspoke ON ItemExtradataTypes(Name)'); con.commit()
con.execute('DROP INDEX IF EXISTS idx_custom_statspoke'); con.commit()
con.close(); print('override removed')"

Verify it's in place (second number should be 3000):

python3 -c "
import sqlite3
con = sqlite3.connect('file:/var/lib/emby/data/library.db?mode=ro', uri=True)
print(con.execute(\"SELECT stat FROM sqlite_stat1 WHERE idx='idxAncestorIds2_1'\").fetchone())"

If the second number is small (e.g. 1 or 4), the override was erased by something running ANALYZE — see the recovery recipe below. Symptom of loss: short/common-term searches suddenly take 30–50 s again.

Results measured on our server after all patches: ST 52 s → 0.08 s, the (29k matches) 27 s → 0.25 s, lord 13 s → 0.008 s, recent-searches 100+ s → a few ms. No regressions in Continue Watching / Next Up / home screens.


Recovery recipe: "searches got slow again after an update/restart"

Refreshes statistics properly AND reapplies the Patch 4 override, then refreshes plans:

python3 -c "
import sqlite3
con = sqlite3.connect('/var/lib/emby/data/library.db', timeout=60)
con.execute('PRAGMA busy_timeout=60000')
con.execute('ANALYZE'); con.commit()
n = con.execute('SELECT COUNT(*) FROM AncestorIds2').fetchone()[0]
con.execute('UPDATE sqlite_stat1 SET stat=? WHERE tbl=? AND idx=?', (f'{n} 3000 1','AncestorIds2','idxAncestorIds2_1'))
con.commit()
con.execute('CREATE INDEX IF NOT EXISTS idx_custom_statspoke ON ItemExtradataTypes(Name)'); con.commit()
con.execute('DROP INDEX IF EXISTS idx_custom_statspoke'); con.commit()
con.close(); print('stats refreshed + override reapplied')"

Removing all patches when Emby ships the official fix

These are workarounds. When an Emby release notes say the search/statistics issues are fixed, remove the patches in the same maintenance window as that update, so the fixed version runs with a stock schema, stock statistics, and stock config. (For ordinary updates where no fix is mentioned: keep the patches, update normally, and afterwards run the recovery recipe above plus re-check the system.xml values.)

1. While the server is still running (old version), drop the custom index (Patch 1):

python3 -c "
import sqlite3
con = sqlite3.connect('/var/lib/emby/data/library.db', timeout=60)
con.execute('PRAGMA busy_timeout=60000')
con.execute('DROP INDEX IF EXISTS idx_custom_UserDatas_LastSearched')
con.commit(); con.close(); print('custom index removed')"

2. Stop Emby:

systemctl stop emby-server

3. Restore system.xml defaults (Patch 3): set DatabaseAnalysisLimit back to 5000 and OptimizeDatabaseOnShutdown back to true. (MaxLibraryDatabaseConnections is ordinary performance tuning, not part of the bug — keep your higher value or restore 5, your choice.)

nano /var/lib/emby/config/system.xml

4. Remove the statistics override (Patches 2/4) by refreshing statistics on the stopped database — no poke needed since every connection will be new on start:

python3 -c "
import sqlite3
con = sqlite3.connect('/var/lib/emby/data/library.db', timeout=60)
con.execute('ANALYZE'); con.commit(); con.close(); print('statistics reset to honest values')"

With the defaults restored in step 3, Emby's own maintenance manages statistics again from here on — nothing custom remains in the database or config.

5. Install the update, then start:

systemctl start emby-server

Verify after the update that search is still fast on the fixed version; if it is not, the patches can be reapplied from the top of this guide at any time.

(The Step 0 backups are unrelated to this procedure — they exist only as a safety net in case something goes wrong while patching.)

 

Edited by flord22
info about previous post being hidden
  • Thanks 2

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...