2009-09-05 48 views
7

我想优化我的mysql查询,以避免'使用临时的,使用filesort'。我可以使用一些帮助。第一;这里是解释使用临时的,在MySQL中使用filesort一个坏主意?

这里是查询

select pf.*,m.login,m.avatar 
from profile_friends pf, members m 
where pf.friend_id = m.id and pf.member_id = 16586 
order by m.lastLogin desc 
limit 0,24; 


mysql> EXPLAIN select pf.*,m.login,m.avatar from profile_friends pf, members m where pf.friend_id = m.id and pf.member_id = 16586 order by m.lastLogin desc limit 0,24; 
+----+-------------+-------+--------+-----------------------------------------------------+-----------------+---------+--------------------------+------+----------------------------------------------+ 
| id | select_type | table | type | possible_keys          | key    | key_len | ref      | rows | Extra          | 
+----+-------------+-------+--------+-----------------------------------------------------+-----------------+---------+--------------------------+------+----------------------------------------------+ 
| 1 | SIMPLE  | pf | ref | member_id_index,friend_id_index      | member_id_index |  4 | const     | 160 | Using where; Using temporary; Using filesort | 
| 1 | SIMPLE  | m  | eq_ref | PRIMARY,member_id_privacy_index,id_last_login_index | PRIMARY   |  4 | mydb.pf.friend_id  | 1 | Using where         | 

有涉及2个表。 ProfileFriends(pf)和会员(m)。此查询只是试图找到这个特定会员ID的'最近'24个朋友。最近意味着按LastLogin日期排序。

谢谢

回答

17

这是一个问题?是啊。

当你处理160行时,这是一个问题吗?不。

“文件排序”是一种方法,而不是一个文件的实际创建和分类整理。如果我们谈论160,000行而不是160行,那么可能有理由考虑进一步的优化。

编辑:此外,您省略了实际的查询运行时间。你正在打索引,只能用几行。如果这个查询花费的时间超过了几分之一秒,那么甚至可能不值得优化。

+3

+1是的,对于160行MySQL甚至可以将临时表保存在内存中,而无需将其写入磁盘。 “Filesort”有点误导,它只意味着它没有索引的好处而被排序。 – 2009-09-05 18:21:37

1

这是编写该查询最有效的方法。

确保pf.friend_id,pf.member_idm.id上有索引。然后它将使用索引来加入表格并过滤结果。

无论如何,由于你的order by,这种情况将会出现。

+4

MySQL将使用'pf.friend_id'上的索引或'pf.member_id'上的索引,但它不会同时使用这两个索引,所以不需要创建多余的索引。但它可以在'(member_id,friend_id)'上使用索引。 – 2009-09-05 02:29:45

2

我想你应该能够避免members (id,lastLogin)—临时/使用索引文件排序依次—但该类型它的矫枉过正,并通过你的判断查询的解释似乎你已经尝试过了吗?

你可以使用profile_friends (member_id,friend_id)上的PRIMARY/UNIQUE KEY来补充它,看看它是如何工作的。

在不得已的,如果执行该查询经常,有这么多的记录,你必须拥有最快的选择可能,你可以进行非规范化你的表和你members.lastLogin列的副本与索引上(member_id,lastLogin)添加到profile_friends。有了这个,你就没有加入,没有文件,没有任何东西。另一方面,每当有许多朋友登录时,你就会有很大的UPDATE查询。同样,对于你正在谈论的那种数字来说,这似乎完全是矫枉过正。

我差点忘了,以解决原来的问题:

使用临时使用文件排序在MySQL中是一个坏主意?

不,它不是。如果你可以很容易地优化它,那么你应该总是寻求“无档案”的查询,但除非它们带来真正的性能问题,否则你不应该担心。 Filesort是查询正常执行的一部分。

相关问题