Chọn hàng ngẫu nhiên (Random Row) trong MySQL
Sử dụng hàm RAND() trong ORDER BY kết hợp LIMIT 1 để lấy 1 hàng ngẫu nhiên từ bảng.
Cú pháp
SELECT * FROM ten_bang ORDER BY RAND() LIMIT 1;
Ví dụ minh họa
Tạo bảng DemoTable735:
mysql> CREATE TABLE DemoTable735 (Amount INT); Query OK, 0 rows affected (0.57 sec)
Chèn dữ liệu:
mysql> INSERT INTO DemoTable735 VALUES(984474734); Query OK, 1 row affected (0.17 sec) mysql> INSERT INTO DemoTable735 VALUES(489393323); Query OK, 1 row affected (0.18 sec) mysql> INSERT INTO DemoTable735 VALUES(23432333); Query OK, 1 row affected (0.17 sec) mysql> INSERT INTO DemoTable735 VALUES(8949933); Query OK, 1 row affected (0.14 sec)
Xem dữ liệu:
mysql> SELECT * FROM DemoTable735;
+-----------+ | Amount | +-----------+ | 984474734 | | 489393323 | | 23432333 | | 8949933 | +-----------+ 4 rows in set (0.00 sec)
Chọn 1 hàng ngẫu nhiên:
mysql> SELECT * FROM DemoTable735 ORDER BY RAND() LIMIT 1;
Kết quả (mỗi lần chạy khác nhau):
+-----------+ | Amount | +-----------+ | 489393323 | +-----------+ 1 row in set (0.00 sec)
⚠️ Vấn đề hiệu suất với bảng lớn
ORDER BY RAND() buộc MySQL:
- Tạo bảng tạm chứa toàn bộ hàng + cột RAND()
- Sắp xếp bảng tạm
- Lấy 1 hàng đầu
→ O(N log N), rất chậm với bảng > 10k hàng.
Giải pháp tối ưu cho bảng lớn
Cách 1: Lấy ID ngẫu nhiên trong phạm vi (cần ID liên tục, ít xóa)
SELECT * FROM DemoTable735 WHERE Id >= (SELECT FLOOR(RAND() * (SELECT MAX(Id) FROM DemoTable735))) ORDER BY Id LIMIT 1;
Cách 2: 2 truy vấn (Application level)
-- Query 1: Lấy COUNT(*) SELECT COUNT(*) INTO @cnt FROM DemoTable735; -- App tính: offset = FLOOR(RAND() * @cnt) -- Query 2: SELECT * FROM DemoTable735 LIMIT @offset, 1;
Cách 3: TABLESAMPLE (MySQL 8.0.23+ - Bernoulli sampling)
SELECT * FROM DemoTable735 TABLESAMPLE BERNOULLI (10) LIMIT 1;
Lấy ~10% bản ghi ngẫu nhiên, sau đó LIMIT 1. Không đảm bảo phân bố đều.
Cách 4: Offset ngẫu nhiên trên Primary Key (khuyên dùng)
SELECT * FROM DemoTable735 WHERE Id >= (SELECT FLOOR(RAND() * ((SELECT MAX(Id) FROM DemoTable735) - (SELECT MIN(Id) FROM DemoTable735) + 1)) + (SELECT MIN(Id) FROM DemoTable735)) ORDER BY Id LIMIT 1;
Tóm tắt khuyến nghị
| Kích thước bảng | Phương pháp khuyên dùng |
|---|---|
| < 1.000 hàng | ORDER BY RAND() LIMIT 1 (đơn giản, chấp nhận được) |
| 1.000 - 100.000 hàng | Cách 2 (2 queries) hoặc Generated Column + Index |
| > 100.000 hàng | Cách 4 (Random PK range) hoặc Reservoir Sampling ở App |