Maison >base de données >tutoriel mysql >Comment puis-je optimiser la fonction ORDER BY RAND() de MySQL pour une sélection de lignes aléatoires plus rapide ?

Comment puis-je optimiser la fonction ORDER BY RAND() de MySQL pour une sélection de lignes aléatoires plus rapide ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-19 22:40:15629parcourir

How Can I Optimize MySQL's ORDER BY RAND() Function for Faster Random Row Selection?

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn