我还在学习MySQL。我可能会犯一个非常基本的错误,我准备在这里训练...正在执行count()计算减慢我的mysql查询?
这个查询试图做的是从我们的网站上选择最高的成员数量的书和食谱评论他们做了。
我做在SQL查询本身总的计算。查询速度很慢(9秒),并且绝对不会扩展,因为我们目前只有400个成员和几千条评论,并且它的增长速度非常快。
我相信它做一个全表扫描,在这里,而且在计算减缓下来,但我不知道的另一种方式来做到这一点,也许需要一些智慧。
这里的SQL语句:
SELECT users.*, COUNT(DISTINCT bookshelf.ID) AS titles, COUNT(DISTINCT book_reviews.ID) as bookreviews, COUNT(DISTINCT recipe_reviews.ID) AS numreviews, COUNT(DISTINCT book_reviews.ID) + COUNT(DISTINCT recipe_reviews.ID) as reviewtotal
FROM users
LEFT OUTER JOIN recipe_reviews ON recipe_reviews.user_id = users.ID
LEFT OUTER JOIN book_reviews ON book_reviews.user_id = users.ID
LEFT OUTER JOIN bookshelf ON users.ID = bookshelf.user_id
GROUP BY users.ID
ORDER BY reviewtotal DESC
LIMIT 8
这里的解释是:
+----+-------------+----------------+-------+-------------------+-------------------+---------+---------------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------+-------+-------------------+-------------------+---------+---------------------+------+---------------------------------+
| 1 | SIMPLE | users | index | NULL | PRIMARY | 4 | NULL | 414 | Using temporary; Using filesort |
| 1 | SIMPLE | recipe_reviews | ref | recipe_reviews_fk | recipe_reviews_fk | 5 | users.ID | 12 | |
| 1 | SIMPLE | book_reviews | ref | user_id | user_id | 5 | users.ID | 4 | |
| 1 | SIMPLE | bookshelf | ref | recipe_reviews_fk | recipe_reviews_fk | 5 | users.ID | 13 | |
+----+-------------+----------------+-------+-------------------+-------------------+---------+---------------------+------+---------------------------------+
UPDATE &解决:
我意识到,和@recursive证实,该查询问题的根源。我从中得到笛卡尔产品。我重写它作为一个子查询系列和最终工作代码是在这里:
SELECT *, bookreviews + recipereviews AS totalreviews
FROM (SELECT users.*,
(SELECT count(*) FROM bookshelf WHERE bookshelf.user_id = users.ID) as titles,
(SELECT count(*) FROM book_reviews WHERE book_reviews.user_id = users.ID) as bookreviews,
(SELECT count(*) FROM recipe_reviews WHERE recipe_reviews.user_id = users.ID) as recipereviews
FROM users) q
这给我以毫秒为单位的结果。还有一些方法可以用JOIN做到这一点。如果你想跟上这一点,请参阅How to add together the results of several subqueries?。
我已经标记了递归的答案是正确的,虽然他的初步答案不是解决方案,但他将它钉在下面的注释中。 – mandel 2010-01-13 16:48:40