ORDER BY RAND()
est lent car le SGBD doit lire toutes les lignes, toutes les trier, juste pour ne conserver que quelques lignes. Ainsi, les performances de cette requête dépendent fortement du nombre de lignes dans la table et diminuent à mesure que le nombre de lignes augmente.
Il n'y a aucun moyen d'optimiser cela.
Il existe cependant des alternatives :
Vous pouvez implémenter "get 5 random rows" en faisant 6 requêtes :
- obtenir le nombre de lignes dans le tableau (vous pouvez mettre celui-ci en cache)
-
faire 5 requêtes avec
OFFSET <random offset from 0 to $number_of_rows-1> LIMIT 1
(c'est-à-dire lire et renvoyer une seule ligne à partir d'un décalage aléatoire)Par exemple :
SELECT * FROM Products OFFSET 42 LIMIT 1
(note :sans adhésion, pour l'instant)Ces requêtes sont très rapides et exécutées dans un temps pratiquement indépendant de la taille de la table.
Cela devrait être beaucoup plus rapide que ORDER BY RAND()
.
Maintenant, pour obtenir une image aléatoire pour chaque produit aléatoire :
SELECT *
FROM (
SELECT *
FROM Products
OFFSET 42 LIMIT 1
) p
JOIN ProductImages pi
ON pi.product_id = p.id
ORDER BY RAND()
LIMIT 1
La requête interne est toujours rapide, et la requête externe ne trie que quelques lignes (en supposant qu'il y a peu d'images par produit), et peut donc toujours utiliser order by rand().