执行count()计算会减慢我的mysql查询吗?

man*_*del 5 mysql sql performance count

我还在学习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
Run Code Online (Sandbox Code Playgroud)

这是解释:

+----+-------------+----------------+-------+-------------------+-------------------+---------+---------------------+------+---------------------------------+
| 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 |                                 | 
+----+-------------+----------------+-------+-------------------+-------------------+---------+---------------------+------+---------------------------------+
Run Code Online (Sandbox Code Playgroud)

更新和解决:

我意识到,并且@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
Run Code Online (Sandbox Code Playgroud)

这给我一个毫秒的结果.还有一些方法可以使用JOIN来完成此操作.请参见如何将几个子查询的结果相加?如果你想跟进这个.

rec*_*ive 2

您可以尝试看看删除修饰符是否有改进DISTINCT。假设DISTINCTed 字段无论如何都是主键,这可能会导致不必要的工作。