sql >> Databasteknik >  >> RDS >> Mysql

Hur kan jag optimera MySQL:s ORDER BY RAND() funktion?

Prova detta:

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

Detta är särskilt effektivt på MyISAM (eftersom COUNT(*) är omedelbar), men även i InnoDB det är 10 gånger effektivare än ORDER BY RAND() .

Huvudtanken här är att vi inte sorterar, utan istället behåller två variabler och beräknar running probability av en rad som ska väljas i det aktuella steget.

Se den här artikeln i min blogg för mer information:

Uppdatering:

Om du bara behöver välja en enda slumpmässig post, prova detta:

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

Detta förutsätter ditt ac_id är fördelade mer eller mindre jämnt.



  1. SQL Buddy – ett webbaserat MySQL-administrationsverktyg

  2. Hur man hittar alla anslutna subgrafer i en oriktad graf

  3. Hur återställer jag en sekvens i Oracle?

  4. Hur du anpassar dina MySQL- och MariaDB-säkerhetskopier med ClusterControl