改进特定MySQL查询以减少CPU /磁盘密集

时间:2011-02-04 21:59:23

标签: mysql

我有一个查询需要花费很长时间才能执行(例如15秒),这只是在一个小的测试数据集上。

我正在寻求帮助改善这一点:

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                                  |
+----+--------------------+---------+------+---------------+------+---------+-------+-------+----------------------------------------------+

我知道它在哪里“坏” - 它正在通过rand()进行连接和订单,这永远不会特别有效。我不确定为什么它没有在“people”表上使用索引 - “uid”是主键并被索引。

查询的目的应该是显而易见的,但对于子孙后代,我正在做的是从人员表中选择1个随机行,其中uid与另一个表中的“朋友”列表匹配。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我从不在生产中使用IN子句。

EXISTS 要么 不存在

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

这是mysql文档:

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

我的建议是学习如何(“不考虑它”)编写EXISTS和NOT EXISTS条款,并将“IN”条款粘贴到牧场(减去偶尔快速查找数据)。

但是对于生产查询,我会说转储“IN”。