Skip to content

Fix slow store_seen_flags_on_imap#8040

Open
link2xt wants to merge 3 commits intomainfrom
link2xt/seen-flags-sql
Open

Fix slow store_seen_flags_on_imap#8040
link2xt wants to merge 3 commits intomainfrom
link2xt/seen-flags-sql

Conversation

@link2xt
Copy link
Collaborator

@link2xt link2xt commented Mar 26, 2026

Fixes #8022

@link2xt link2xt force-pushed the link2xt/seen-flags-sql branch from ac74f67 to 85fdc95 Compare March 26, 2026 03:16
@link2xt link2xt marked this pull request as ready for review March 26, 2026 04:21
@link2xt link2xt changed the title fix: move sorting outside of SQL query in store_seen_flags_on_imap Fix slow store_seen_flags_on_imap Mar 26, 2026
@link2xt link2xt force-pushed the link2xt/seen-flags-sql branch 2 times, most recently from a3935d2 to f6d3bfb Compare March 26, 2026 10:35
link2xt added 2 commits March 26, 2026 11:36
With `ORDER BY` statement SQLite searches
the `imap` table by `transport_id` and for each found row
scans the whole `imap_markseen` table.
Number of `imap` entries for each `transport_id`
is usually large as we need to know
which UIDs to delete on IMAP server
when deleting a message.

```
sqlite> EXPLAIN QUERY PLAN
SELECT imap.id, uid, folder FROM imap, imap_markseen
WHERE imap.id = imap_markseen.id
AND imap.transport_id=?
AND target = folder
ORDER BY folder, uid;
QUERY PLAN
|--SEARCH imap USING INDEX sqlite_autoindex_imap_1 (transport_id=?)
`--SCAN imap_markseen
```

Without `ORDER BY` statement SQLite scans `imap_markseen`
table which is expected to be small,
and then searches `imap` table by `rowid` for each found result.

```
sqlite> EXPLAIN QUERY PLAN
SELECT imap.id, uid, folder FROM imap, imap_markseen
WHERE imap.id = imap_markseen.id
AND imap.transport_id=?
AND target = folder;
QUERY PLAN
|--SCAN imap_markseen
`--SEARCH imap USING INTEGER PRIMARY KEY (rowid=?)
```

Query planning was tested with SQLite 3.52.0.
It is possible to explictly make
query planner move sorting to the last step
with `ORDER +folder, +uid`, but this is not recommended
in SQLite documentation
(see <https://www.sqlite.org/optoverview.html#uplus>).

It is also possible to add indexes,
but indexes use space,
adding them requires an SQL migration,
and each index needs to be updated so it will slow down writes.
@link2xt link2xt force-pushed the link2xt/seen-flags-sql branch 2 times, most recently from 3289d71 to 0a6aff5 Compare March 26, 2026 11:04
…ekeeping

Previously transports deleted via sync messages left unused `imap` entries.
@link2xt link2xt force-pushed the link2xt/seen-flags-sql branch from 0a6aff5 to bff5133 Compare March 26, 2026 11:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Slow SQL query in store_seen_flags_on_imap

1 participant