Như đã đề cập trong Bản phát hành quan trọng của MySQL 8.0.0 có sẵn ,
Tôi cho rằng đây là nguyên nhân của hành vi mà tôi đang quan sát thấy trong các phiên bản MySQL mới hơn. Gợi ý đã đề cập có thể được sử dụng với MySQL 8.0 để buộc RAND () chỉ được gọi một lần:
SELECT /* NO_MERGE(q) */
q.i,
q.r,
q.r
FROM (
SELECT
id AS i,
(FLOOR(RAND(100) * 4)) AS r
FROM t
) AS q;
+---+-----+-----+
| i | r | r |
+---+-----+-----+
| 1 | 0 | 0 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| 4 | 2 | 2 |
| 5 | 1 | 1 |
+---+-----+-----+
Tuy nhiên, điều này không có sẵn trong 5.7. Để đạt được hành vi mong muốn với 5.7, hãy thêm LIMIT <a very high number>
vào định nghĩa bảng dẫn xuất (tôi đang sử dụng LONG_MAX có chữ ký bên dưới). Cảm ơn Roy Lyseng về giải pháp
này .
SELECT
q.i,
q.r,
q.r
FROM (
SELECT
id AS i,
(FLOOR(RAND(100) * 4)) AS r
FROM t LIMIT 9223372036854775807
) AS q;
+---+-----+-----+
| i | r | r |
+---+-----+-----+
| 1 | 0 | 0 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| 4 | 2 | 2 |
| 5 | 1 | 1 |
+---+-----+-----+
Như philipxy được đề cập trong nhận xét, kết quả của một biểu thức truy vấn phải được xác định chặt chẽ bất kể bất kỳ tối ưu hóa nào đang được áp dụng. Có nghĩa là nó là một lỗi trình tối ưu hóa trong MySQL 5.7 / 8.0.