I’m implementing a dialogs search module on a messaging app. Retrieving the list of dialogs names would be as follows:
select coalesce(c.custom_name, u.username) as dialog_name
from user_chats uc
join chats c using(chat_id)
left join users u on uc.peer_id = u.user_id
So, basically, a dialog name is either a peer’s username if it is a direct chat, or a custom name if it’s something else (a group chat, for instance). I need a search on dialog_name, a value that’s dynamically built on each query. Both chats.custom_name and users.username have indexes on them, but I can’t think of a way to perform this search effectively and using indexes. Can someone, please, help me?
p.s. user_chats consists of user_id (user_id of the client), sel (selector, user_id of peer if direct, 2 billions + sequence for client’s groups if group chat), chat_id, peer_id (if direct – user_id of peer)
2
Answers
I ended up creating a separate chat_names table, which eliminates the need to use COALESCE in WHERE clause. As for my initial question, I don't think it is possible to use indexes for a COALESCE of values from different tables
You can use function based index – expression index.
I tried this on sample table which has a 10 million records.
When I use this query:
After adding expression index to my table:
My query results this plan:
This is gets best performance over using