Some more FORCE INDEX - #870
Conversation
| log.warning( | ||
| "Expected to create imapuid, but existing row found", | ||
| remote_msg_uid=raw_message.uid, | ||
| existing_imapuid=existing_imapuid.id, |
There was a problem hiding this comment.
It's not really interesting to know the id column here, all we care about is the triple (account_id, folder_id, imap_uid) is unique, which can be known from the unique index (account_id, folder_id, imap_uid DESC) which is covering for this query. Faster.
| session.query(ImapUid) | ||
| .filter( | ||
| ImapUid.account_id == account_id, | ||
| ImapUid.folder_id == folder_id, | ||
| ImapUid.msg_uid.in_(new_flags), | ||
| ) | ||
| .with_hint( | ||
| ImapUid, "FORCE INDEX (ix_imapuid_account_id_folder_id_msg_uid_desc)" | ||
| ) |
There was a problem hiding this comment.
Not a covering index since we retrieve other columns, but does not make anything slower, just switches the index.
| .with_hint( | ||
| ImapUid, | ||
| "FORCE INDEX (ix_imapuid_account_id_folder_id_msg_uid_desc)", | ||
| ) |
There was a problem hiding this comment.
Not a covering index since we retrieve other columns, but does not make anything slower, just switches the index.
f757e8f to
90d3495
Compare
| for uid, in db_session.query(ImapUid.msg_uid) | ||
| .filter( | ||
| ImapUid.account_id == self.account_id, | ||
| ImapUid.folder_id == self.folder_id, | ||
| ) | ||
| .with_hint( | ||
| ImapUid, "FORCE INDEX(ix_imapuid_account_id_folder_id_msg_uid_desc)" |
There was a problem hiding this comment.
Covering index since we filter by account_id, folder_id and retrieve msg_uid.
| load_only("msg_uid"), joinedload("message").load_only("g_msgid") | ||
| ) | ||
| .filter_by(account_id=self.account_id, folder_id=self.folder_id) | ||
| .filter( |
There was a problem hiding this comment.
Covering index since we filter by account_id, folder_id and retrieve msg_uid.
d15eead to
a81b436
Compare
mrhiggi-close
left a comment
There was a problem hiding this comment.
Looks good, forcing these to use the new index makes sense.
This rewrites one query which is off the beaten path and not that important from the performance point of view, I am doing this rather for consistency because this query could be faster. It also makes all those queries easier to find in the source code. This part of code is only executed if there's a new message in your folder which is "rare" compared to everything else that happens.
Also the code before actually fetches the row (to know the id) and we are only interested to know if it exists. That's what EXISTS clause in SQL exists for. This way we can read everything from the index and not look at the table at all because all the columns involved are already in the index.
Before
After
It also adds the hints in some other parts just to switch away from the old index to the new index, my objective is to be sure that I can safely remove the old index.
Memo, how to check that index is no longer used in MySQL: