Compare commits

...

2 Commits

Author SHA1 Message Date
link2xt
59dce259b3 use unlikely() hint instead of forcing an index 2025-03-01 16:11:32 +00:00
link2xt
7ef3884ced fix: force usage of msgs.starred column index 2025-02-28 17:30:00 +00:00

View File

@@ -1313,10 +1313,37 @@ impl Message {
/// UI can use this to show a symbol beside the message, indicating it was saved.
/// The message can be un-saved by deleting the returned message.
pub async fn get_saved_msg_id(&self, context: &Context) -> Result<Option<MsgId>> {
// We force usage of `msgs_index5`
// which indexes `msgs.starred` column
// using `unlikely()` here.
//
// Otherwise with SQLite 3.49.1
// if you run ANALYZE on the database
// that has no starred messages,
// query planner decides not to use the index:
//
// sqlite> EXPLAIN QUERY PLAN SELECT id FROM msgs WHERE starred=? AND chat_id!=?;
// QUERY PLAN
// `--SEARCH msgs USING INDEX msgs_index5 (starred=?)
// sqlite> ANALYZE;
// sqlite> EXPLAIN QUERY PLAN SELECT id FROM msgs WHERE starred=? AND chat_id!=?;
// QUERY PLAN
// `--SCAN msgs
//
// Dropping created sqlite_stat1 and sqlite_stat4 tables
// and reconnecting helps.
//
// Even if we don't run ANALYZE or PRAGMA OPTIMIZE
// as of 2025-02-28, ANALYZE is supposed to improve performance
// and this demonstrates a bug in the query planner.
//
// See <https://sqlite.org/queryplanner-ng.html#howtofix>
// and <https://sqlite.org/lang_corefunc.html#unlikely>
// for details.
let res: Option<MsgId> = context
.sql
.query_get_value(
"SELECT id FROM msgs WHERE starred=? AND chat_id!=?",
"SELECT id FROM msgs WHERE unlikely(starred=?) AND chat_id!=?",
(self.id, DC_CHAT_ID_TRASH),
)
.await?;