优化前
SELECT m.id,m.channel_id,m.sender_id,m.create_at,m.type,m.content,m.file_id,m.create_at ,
u.name,u.nickname,u.online_status,u.avatar_url,u.name_first_letter,
f.name AS file_name,f.extension,f.size,f.mime_typ,f.width,f.height,f.path,f.thumb_width,f.thumb_height
FROM im_message m INNER JOIN t_im_user u
ON m.sender_id=u.id LEFT JOIN im_file f ON m.file_id=f.id
WHERE m.channel_id= 'b9f090a0bf30428da5a9ce7e3e3772ca' AND delete_at=0
and m.create_at <= 1691561693244
ORDER BY m.create_at desc
LIMIT 20
使用explain进行查看sql执行情况如下:
可以看到Extra一栏里面的Using temporary; Using filesort,使用了临时表和filesort排序,当查询数量过多,或者排序没有正确使用索引都会出现Using temporary,导致大量的IO操作严重影响查询性能。
优化查询语句,使用FORCE INDEX强制使用索引。
优化后
SELECT m.id,m.channel_id,m.sender_id,m.create_at,m.type,m.content,m.file_id,m.create_at ,
u.name,u.nickname,u.online_status,u.avatar_url,u.name_first_letter,
f.name AS file_name,f.extension,f.size,f.mime_typ,f.width,f.height,f.path,f.thumb_width,f.thumb_height
FROM im_message m FORCE INDEX(order_index) INNER JOIN t_im_user u
ON m.sender_id=u.id LEFT JOIN im_file f ON m.file_id=f.id
WHERE m.channel_id= 'b9f090a0bf30428da5a9ce7e3e3772ca' AND delete_at=0
and m.create_at <= 1691561693244
ORDER BY m.create_at desc
LIMIT 20