Mysql query takes 15+ sec to fetch data. I have given my query below.
FYI: messages table has 5L (500,000) rows of data so it takes long time.
select distinct ur.id, ur.user_name as name, ur.online, ur.chat_status, ur.updated_at, ur.profile_image, ur.role_id, ( SELECT created_at from messages where from_role_user_id = ur.id OR to_role_user_id = ur.id Order by created_at DESC LIMIT 1 ) as message_at, ( SELECT count(is_read) from messages where from_role_user_id = ur.id AND to_role_user_id = 1 AND is_read = 0 ) as count, r.name as role from role_users ur left join roles r ON r.id = ur.role_id where ur.id != 1 AND r.name IN ('superadmin', 'candidate', 'admin', 'manager', 'business_unit','client') AND ur.chat_status != 'offline' AND ur.is_deleted = 0 AND ur.user_name IS NOT NULL order by message_at DESC LIMIT 10;
Can any one help me to optmize the query.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
-
The first subquery would probably be faster this way:
( SELECT MAX(created_at) from messages where from_role_user_id = ur.id OR to_role_user_id = ur.id ) as message_at,
-
This may be even faster:
SELECT GREATEST( ( SELECT MAX(created_at) FROM messages WHERE from_role_user_id = ur.id ), ( SELECT MAX(created_at) FROM messages WHERE to_role_user_id = ur.id ) )
-
with two indexes:
INDEX(from_role_user_id, created_at),
INDEX(to_role_user_id, created_at) -
COUNT(x)
counts how many rows havex IS NOT NULL
.SUM(y)
adds up the y’s, ignoringNULLs
. The usual way to count rows isCOUNT(*)
.( SELECT count(*) from messages where from_role_user_id = ur.id AND to_role_user_id = 1 AND is_read = 0 ) as count,
- And have `INDEX(from_role_user_id, to_role_user_id, is_read)
-
If the
DISTINCT
is not really needed, it will avoid an extra pass over the data, hence faster. -
Please provide
EXPLAIN SELECT ...
- It may be better to find the ids of the 10 messages first, then go to the effort of running those subqueries on ly 10 times.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0