Mysql
 sql >> Base de données >  >> RDS >> Mysql

La colonne rand() de la sous-requête est réévaluée pour chaque sélection répétée dans MySQL 5.7/8.0 par rapport à MySQL 5.6

Comme mentionné dans La version MySQL 8.0.0 Milestone est disponible ,

Je suppose que c'est la cause du comportement que j'observe dans les nouvelles versions de MySQL. L'astuce mentionnée peut être utilisée avec MySQL 8.0 pour forcer RAND() à n'être appelé qu'une seule fois :

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

Ceci n'est cependant pas disponible dans 5.7. Pour obtenir le comportement souhaité avec 5.7, ajoutez LIMIT <a very high number> à la définition de la table dérivée (j'utilise signé LONG_MAX ci-dessous). Merci à Roy Lyseng pour cette solution de contournement .

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

En tant que philippie mentionné dans le commentaire, le résultat d'une expression de requête doit être strictement défini quelles que soient les optimisations appliquées. Ce qui signifie qu'il s'agit d'un bogue d'optimisation dans MySQL 5.7/8.0.