Optimisation de la fonction ORDER BY RAND() de MySQL pour une sélection aléatoire plus rapide des lignes
La fonction ORDER BY RAND() de MySQL est largement utilisée pour la sélection aléatoire lignes d'une table. Cependant, cela peut s’avérer inefficace, notamment pour les grandes tables ou les mises à jour fréquentes. Cette inefficacité est évidente dans les journaux de requêtes lents, où les requêtes contenant ORDER BY RAND() contribuent de manière significative au ralentissement.
Une solution potentielle est la méthode MySQLPerformanceBlog, qui implique de diviser la requête en plusieurs sous-requêtes. Cependant, cette technique peut ne pas être adéquate dans toutes les situations.
Une approche alternative
Une approche alternative qui offre une efficacité améliorée est présentée ci-dessous :
SELECT * FROM ( SELECT @cnt := COUNT(*) + 1, @lim := 10 FROM t_random ) vars STRAIGHT_JOIN ( SELECT r.*, @lim := @lim - 1 FROM t_random r WHERE (@cnt := @cnt - 1) AND RAND(20090301) < @lim / @cnt ) i
Cette méthode fonctionne en calculant la probabilité d'exécution de chaque ligne sélectionnée en fonction de deux variables. En utilisant STRAIGHT_JOIN, l'ordre des lignes dans le résultat est préservé, fournissant ainsi une sélection aléatoire.
Cas spécifique : sélection d'un seul enregistrement aléatoire
Si l'exigence est pour sélectionner un seul enregistrement aléatoire, la requête suivante peut être utilisée :
SELECT aco.* FROM ( SELECT minid + FLOOR((maxid - minid) * RAND()) AS randid FROM ( SELECT MAX(ac_id) AS maxid, MIN(ac_id) AS minid FROM accomodation ) q ) q2 JOIN accomodation aco ON aco.ac_id = COALESCE ( ( SELECT accomodation.ac_id FROM accomodation WHERE ac_id > randid AND ac_status != 'draft' AND ac_images != 'b:0;' AND NOT EXISTS ( SELECT NULL FROM accomodation_category WHERE acat_id = ac_category AND acat_slug = 'vendeglatohely' ) ORDER BY ac_id LIMIT 1 ), ( SELECT accomodation.ac_id FROM accomodation WHERE ac_status != 'draft' AND ac_images != 'b:0;' AND NOT EXISTS ( SELECT NULL FROM accomodation_category WHERE acat_id = ac_category AND acat_slug = 'vendeglatohely' ) ORDER BY ac_id LIMIT 1 ) )
Cette requête suppose une distribution uniforme de ac_id valeurs.
En employant ces approches alternatives, vous pouvez améliorer considérablement les performances des requêtes MySQL qui impliquent la fonction ORDER BY RAND().
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!