sql >> Database >  >> RDS >> Mysql

Hoe kan ik de ORDER BY RAND()-functie van MySQL optimaliseren?

Probeer dit:

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

Dit is vooral efficiënt op MyISAM (sinds de COUNT(*) is direct), maar zelfs in InnoDB het is 10 keer efficiënter dan ORDER BY RAND() .

Het belangrijkste idee hier is dat we niet sorteren, maar in plaats daarvan twee variabelen behouden en de running probability berekenen. van een rij die moet worden geselecteerd in de huidige stap.

Zie dit artikel in mijn blog voor meer details:

Bijwerken:

Als u slechts één willekeurig record hoeft te selecteren, probeer dan dit:

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

Hierbij wordt ervan uitgegaan dat uw ac_id 's worden min of meer gelijkmatig verdeeld.



  1. Een HTML-e-mail verzenden vanuit SQL Server (T-SQL)

  2. Totaal aantal rijen krijgen bij gebruik van LIMIT?

  3. Oracle:hoe converteer ik hex naar decimaal in Oracle SQL?

  4. Grote objectgegevens invoegen in Salesforce.com vanuit SQL Server