Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Làm cách nào để tối ưu hóa hàm ORDER BY RAND () của MySQL?

Hãy thử điều này:

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

Điều này đặc biệt hiệu quả trên MyISAM (kể từ COUNT(*) là tức thì), nhưng ngay cả trong InnoDB nó là 10 hiệu quả hơn gấp nhiều lần so với ORDER BY RAND() .

Ý tưởng chính ở đây là chúng tôi không sắp xếp, nhưng thay vào đó giữ hai biến và tính toán running probability của một hàng sẽ được chọn ở bước hiện tại.

Xem bài viết này trong blog của tôi để biết thêm chi tiết:

Cập nhật:

Nếu bạn cần chọn trừ một bản ghi ngẫu nhiên, hãy thử cách này:

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

Điều này giả định ac_id của bạn được phân phối nhiều hơn hoặc ít hơn đồng đều.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL có nên đặt múi giờ thành UTC không?

  2. Câu lệnh MySQL TABLE

  3. # 1055 - Biểu thức của danh sách SELECT không nằm trong mệnh đề GROUP BY và chứa cột không được tổng hợp, cột này không tương thích với sql_mode =only_full_group_by

  4. Làm cách nào để biết giao dịch nào đang gây ra trạng thái khóa siêu dữ liệu bảng Đang chờ?

  5. Cách nhập và xuất tệp CSV bằng PHP và MySQL