2011-02-04 62 views
0

我有正在一个非常非常长的时间来执行(如15秒),这是只在一个小测试数据集的查询。改进具体MySQL查询要少CPU /磁盘密集型

我在寻找帮助改善这一点:

describe SELECT * from people where uid in (SELECT uid2 from friends where uid1=PHP_UID_VARIABLE) order by rand() limit 1; 
+----+--------------------+---------+------+---------------+------+---------+-------+-------+----------------------------------------------+ 
| id | select_type  | table | type | possible_keys | key | key_len | ref | rows | Extra          | 
+----+--------------------+---------+------+---------------+------+---------+-------+-------+----------------------------------------------+ 
| 1 | PRIMARY   | people | ALL | NULL   | NULL | NULL | NULL | 6726 | Using where; Using temporary; Using filesort | 
| 2 | DEPENDENT SUBQUERY | friends | ref | uid1,uid2  | uid1 | 8  | const | 15501 | Using where         | 
+----+--------------------+---------+------+---------------+------+---------+-------+-------+----------------------------------------------+ 

我知道它是“坏” - 它同时使用了加入和兰德公司的订单(),它永远不会成为特别有效。我不确定为什么它没有在“人员”表上使用索引 - “uid”是主键并被索引。

查询的目的应该是足够明显,但对于后人,我在做什么是选择从人民表所在的UID的“好友”列表匹配另一个表1个随机行。

回答

3

试试这个

SELECT p.* 
FROM friends AS f 
LEFT JOIN people AS p ON f.uid2 = p.uid 
WHERE f.uid1=PHP_UID_VARIABLE 
ORDER BY RAND() 
LIMIT 1 
+0

非常好,效果很好。现在要弄清楚它是如何工作的更好,所以我写的比我原来的更有效的查询:) – 2011-02-04 22:11:05

0

我从来没有在生产中使用IN子句。

EXISTS 或 NOT EXISTS

现在,有人说没关系。有人说这很重要。 实验是确定的真实方法。

下面是MySQL文档:

http://dev.mysql.com/doc/refman/5.0/en/exists-and-not-exists-subqueries.html

我的建议是要学会(“不假思索”)写EXISTS和NOT EXISTS子句,并坚持“IN”的条款放牛(减去偶尔快速查看数据)。

但对于生产问题,我会说转储“IN”。