I would start with an index in the message table. A component index that will help cover the connection, as I have in the sample request below ... Index on (user_id, deleted, read_state, from_id).
Next, an explanation of my process. I make a preliminary request from the dialog table as UNION, but each of them accordingly captures the opposite identifier for "LinkToUser" for the next loop associated with the user table after matching with "OR", as in the where clause. Getting qualified records ahead and simplifying can help you.
The next part will indicate the index for your posts. I am making a left join based on a specific user, remote = 0 and SPECIFICALLY read_state = 0. Using the index, it will either find a match or it wonβt. Thus, your Selected field (! 0 in ...) is simply simplified to an IS NULL check.
SELECT u.id as uid, u.name, avatar, avatar_date, driver, m.id AS mid, m.msg, m.removed, m.from_anonym_id, m.to_anonym_id, (m.date DIV 1000) AS date, from_id = 162077 as outbox, msgFrom.from_id IS NULL as read_state FROM ( select distinct d1.*, d1.uid2 as LinkToUser from dialog d1 where d1.uid1 = 162077 union select d2.*, d2.uid1 as LinkToUser from dialog d2 where d2.uid2 = 162077 ) Qualified JOIN Users u ON Qualified.LinkToUser = u.id JOIN Messages m ON Qualified.mid = m.id LEFT JOIN Messages msgFrom ON msgFrom.user_id = 160277 AND msgFrom.Removed = 0 AND msgFrom.Read_State = 0 AND ( m.from_id = msgFrom.from_id OR m.user_id = msgFrom.from_id ) ORDER BY Qualified.mid DESC LIMIT 0, 101;
you may need to play a little with him, maybe change something like ..
if( msgFrom.from_id IS NULL, 0, msgFrom.read_state ) as Read_State
EXPLANATIONS
Zeusakm, your individual read_state field, as written, will ONLY return 1 or 0, since this is a logical condition NOT - the value zero in the selected message list. It will never return -1, as you indicated in your comment. My version does the same. If it finds zero, return zero .. if it cannot find zero, it returns 1 because the comparison value will be NULL, and thus "IsThisValue IS NULL" returns true, which matches flag 1.
So, we hope this clarifies what I'm doing with the left join for you. Explicitly looking for the user ID, the remote state and the read state and (from or match the user ID).