我还在学习MySQL.我可能会犯一个非常基本的错误,我准备在这里受到惩罚……
此查询尝试做的是根据他们所做的书籍和食谱评论的数量从我们的网站中选择最高成员.
我正在计算SQL查询本身的总数.考虑到目前为止我们只有400名成员和几千条评论并且它的增长速度非常快,因此查询速度很慢(9秒)并且肯定无法扩展.
我认为它在这里进行全表扫描,并且计算速度正在减慢,但我不知道另一种方法可以做到这一点,并且会喜欢一些智慧.
这是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 | |
+----+-------------+----------------+-------+-------------------+-------------------+---------+---------------------+------+---------------------------------+
更新&解决了:
我意识到,并且@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?.
最佳答案
您可能会尝试查看删除DISTINCT修饰符是否有所改进.假设DISTINCTed字段无论如何都是主键,这可能会导致不必要的工作.