Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie kann ich die Funktion ORDER BY RAND() von MySQL optimieren?

Versuchen Sie Folgendes:

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

Dies ist besonders effizient auf MyISAM (da der COUNT(*) ist sofort), aber sogar in InnoDB es ist 10 mal effizienter als ORDER BY RAND() .

Die Hauptidee dabei ist, dass wir nicht sortieren, sondern stattdessen zwei Variablen behalten und die running probability berechnen einer Zeile, die im aktuellen Schritt ausgewählt werden soll.

Weitere Einzelheiten finden Sie in diesem Artikel in meinem Blog:

Aktualisierung:

Wenn Sie nur einen einzigen zufälligen Datensatz auswählen müssen, versuchen Sie Folgendes:

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
        )
        )

Dies setzt Ihre ac_id voraus 's werden mehr oder weniger gleichmäßig verteilt.