Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

MySQL: เรียงลำดับสุ่มด้วยคอลัมน์ค่าสุ่ม (RAND)

การสร้างคอลัมน์ค่าสุ่มชั่วคราวเพื่อเรียงลำดับสุ่ม

ใช้ Subquery สร้างคอลัมน์ RAND() + 1 (ค่า 1.0 - 2.0) แล้ว ORDER BY RandomRecord DESC เพื่อเรียงสุ่ม ทำได้ใน Query เดียวโดยไม่ต้อง ALTER TABLE

ตัวอย่างการใช้งาน

สร้างตารางและเพิ่มข้อมูล:

mysql> CREATE TABLE DemoTable (
    -> StudentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> StudentName VARCHAR(20)
    -> );
Query OK, 0 rows affected (0.57 sec)

mysql> INSERT INTO DemoTable(StudentName) VALUES('Larry'),('Sam'),('Mike'),('Carol'),('Robert'),('Chris');
Query OK, 6 rows affected (0.15 sec)

ข้อมูลตามลำดับ Id:

mysql> SELECT * FROM DemoTable;
+-----------+-------------+
| StudentId | StudentName |
+-----------+-------------+
| 1         | Larry       |
| 2         | Sam         |
| 3         | Mike        |
| 4         | Carol       |
| 5         | Robert      |
| 6         | Chris       |
+-----------+-------------+
6 rows in set (0.00 sec)

สร้างคอลัมน์สุ่มและเรียง DESC:

mysql> SELECT * FROM (
    ->     SELECT StudentName, RAND() + 1 AS RandomRecord FROM DemoTable
    -> ) AS tbl
    -> ORDER BY RandomRecord DESC;
+-------------+--------------------+
| StudentName | RandomRecord       |
+-------------+--------------------+
| Carol       | 1.8973721451101566 |
| Chris       | 1.7821308670399065 |
| Mike        | 1.4640037673190271 |
| Larry       | 1.4134691557041081 |
| Sam         | 1.1408822407395414 |
| Robert      | 1.0948494543273461 |
+-------------+--------------------+
6 rows in set (0.00 sec)

คำอธิบาย

  • RAND() คืนค่า Float 0.0 - 1.0 (ไม่รวม 1)
  • RAND() + 1 ทำให้ช่วง 1.0 - 2.0 (กันไม่ให้เป็น 0)
  • Subquery (Derived Table) ต้องมี Alias (AS tbl)
  • ORDER BY RandomRecord DESC → ค่า RAND สูงสุดอยู่บน

วิธีอื่น: ORDER BY RAND() โดยตรง

SELECT * FROM DemoTable ORDER BY RAND() LIMIT 10;

ง่ายกว่า แต่效能一样 (Full Scan + Sort) ใช้ได้กับตารางเล็ก

ข้อควรระวังประสิทธิภาพ

ORDER BY RAND() ช้ามากสำหรับตารางใหญ่ (O(N log N) Sort + No Index)

วิธีเร็วกว่าสำหรับ Random Sampling:

  1. WHERE RAND() < 0.01 (Bernoulli Sampling) ~1% rows, ไม่ต้อง Sort
  2. Offset แบบสุ่ม: SELECT * FROM t WHERE Id >= (SELECT FLOOR(RAND() * (SELECT MAX(Id) FROM t))) ORDER BY Id LIMIT 10;
  3. Pre-computed Random Column: เพิ่ม Col rand_sort INT, Update บ้างครั้ง, Index บนมัน, ORDER BY rand_sort LIMIT 10