SORU
7 AĞUSTOS 2009, Cuma


Nasıl optimize MySQL'RAND TARAFINDAN SİPARİŞ verebilir miyim() fonksiyonu?

mysql-slow.log içine baktığımda benim sorguları optimize etmek istiyorum.

Yavaş sorgularım çoğu ORDER BY RAND() içerir. Veremem gerçek bir çözüm bu sorunu gidermek için bulacaksınız. Var MySQLPerformanceBlog olası bir çözüm ama bunun yeterli olduğunu sanmıyorum. Kötü optimize (ya da sık sık güncellenen, kullanıcı tarafından yönetilen) tabloları üzerinde çalışmıyor veya PHP-üretilen rastgele satır seçmek için önce iki veya daha fazla sorgular çalıştırmak için ihtiyacım var.

Bu sorun için herhangi bir çözüm var mı?

Teşekkürler!

Kukla bir örnek:

SELECT  accomodation.ac_id,
        accomodation.ac_status,
        accomodation.ac_name,
        accomodation.ac_status,
        accomodation.ac_images
FROM    accomodation, accomodation_category
WHERE   accomodation.ac_status != 'draft'
        AND accomodation.ac_category = accomodation_category.acat_id
        AND accomodation_category.acat_slug != 'vendeglatohely'
        AND ac_images != 'b:0;'
ORDER BY
        RAND()
LIMIT 1

CEVAP
7 AĞUSTOS 2009, Cuma


Bunu deneyin:

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

Bu MyISAM üzerinde özellikle etkilidir COUNT(*) anlık olduğundan), ama bile InnoDB 10 ORDER BY RAND() daha verimli.

Ana fikir, ama bunun yerine iki değişken sıralama tutmak ve geçerli adım seçilecek bir satır running probability hesaplamak istemiyoruz.

Daha fazla ayrıntı için: blogumda bu makaleye bakın

Güncelleme:

Eğer tek rastgele bir kayıt ama seçmek gerekirse, bu deneyin:

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

Bu **15'veya daha az eşit. dağıtılmış s senin varsayar

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • celebrateubuntu

    celebrateubu

    23 Mayıs 2011
  • Menglong Tav

    Menglong Tav

    18 Temmuz 2010
  • Shylo Sharity

    Shylo Sharit

    27 EKİM 2011