fix: Use .find_by instead .where().first (#12402)
While investigating a customer-reported issue, I found that some emails
were appearing late in Chatwoot. The root cause was query timeouts.
It only happened for emails with an in_reply_to header. In these cases,
Chatwoot first checks if a message exists with message_id = in_reply_to.
If not, it falls back to checking conversations where
additional_attributes->>'in_reply_to' = ?.
We were using:
```rb
@inbox.conversations.where("additional_attributes->>'in_reply_to' = ?", in_reply_to).first
```
This looked harmless, but .first caused timeouts. Without .first, the
query ran fine. The issue was the generated SQL:
```sql
SELECT *
FROM conversations
WHERE inbox_id = $1
AND (additional_attributes->>'in_reply_to' = '<in-reply-to-id>')
ORDER BY id ASC
LIMIT $2;
```
The ORDER BY id forced a full scan, even with <10k records.
The fix was to replace .first with .find_by:
```rb
@inbox.conversations.find_by("additional_attributes->>'in_reply_to' = ?", in_reply_to)
```
This generates:
```sql
SELECT *
FROM conversations
WHERE inbox_id = $1
AND (additional_attributes->>'in_reply_to' = '<in-reply-to-id>')
LIMIT $2;
```
This avoids the scan and runs quickly without needing an index.
By the way, Cursor and Claude failed
[here](https://github.com/chatwoot/chatwoot/pull/12401), it just kept on
adding the index without figuring out the root cause.
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
@@ -42,7 +42,7 @@ class Imap::ImapMailbox
|
||||
|
||||
message = @inbox.messages.find_by(source_id: in_reply_to)
|
||||
if message.nil?
|
||||
@inbox.conversations.where("additional_attributes->>'in_reply_to' = ?", in_reply_to).first
|
||||
@inbox.conversations.find_by("additional_attributes->>'in_reply_to' = ?", in_reply_to)
|
||||
else
|
||||
@inbox.conversations.find(message.conversation_id)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user