Je pense que toute personne ayant eu à analyser de grosses tables pour en tirer du reporting a déjà effectué ce genre de requêtes :
SELECT *, (SELECT COUNT(DISTINCT(l.like_id)) FROM like l WHERE l.news_id = n.news_id) AS nb_likes FROM news n WHERE blabla
Sauf qu'imaginons que vous ayez 1 million de news, MySQL va effectuer 1 million et 1 requêtes pour récupérer l'ensemble:
- 1 requête pour récupérer les 1M de news
- 1M de requêtes pour récupérer le nombre de likes par news
La solution à implémenter pour optimiser le tout consiste à joindre directement le sous-ensemble avec les likes et travailler in-fine sur l'ensemble des 2 :
SELECT * COUNT(DISTINCT(l.like_id)) AS nb_likes FROM ( SELECT * FROM news n WHERE blabla ) AS n JOIN like l ON n.news_id = l.news_id GROUP BY l.news_id
On obtient le même résultat en seulement 3 requêtes :
- 1 requête pour récupérer les 1M de news
- 1 requête pour joindre le sous-ensemble de news avec l'ensemble des likes
- 1 requête pour grouper les 2 et en déduire le count ainsi que les infos de vos news
La différence de performance est exponentielle, dans mon cas avec une table de 1M de recordsets, je suis passé de 30s à 0.02s.
SELECT
n.*,
COUNT(DISTINCT(l.like_id)) AS nb_likes
FROM
news n
JOIN like l ON n.news_id = l.news_id
WHERE
blabla
GROUP BY
l.news_id;