Действительно ли выполнение является количеством () вычисление, замедляющее мой запрос mysql?

Я все еще узнаю о 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 |                                 | 
+----+-------------+----------------+-------+-------------------+-------------------+---------+---------------------+------+---------------------------------+

ОБНОВИТЕ И РЕШЕННЫЙ:

Я понял, и подтвержденный @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

Это дает мне результат в миллисекундах. Существуют также способы сделать это с СОЕДИНЕНИЯМИ. Посмотрите, Как добавить вместе результаты нескольких подзапросов? если Вы хотите развить это.

5
задан Community 23 May 2017 в 11:46
поделиться