优化前

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