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