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

  • hitcreatormusic2

    hitcreatormu

    21 Mayıs 2010
  • Hot For Nutrition

    Hot For Nutr

    26 ŞUBAT 2007
  • kev5124

    kev5124

    9 Kasım 2008