Imaginez avoir un outil capable de détecter automatiquement les problèmes de performances JPA et de mise en veille prolongée. L’optimiseur d’hypersistance est cet outil!
Introduction
Dans cet article, nous allons voir comment nous pouvons trier un jeu de résultats de requête SQL en utilisant une clause ORDER BY qui prend une fonction ALÉATOIRE fournie par une fonction spécifique à la base de données.
C’est une astuce très pratique, surtout lorsque vous souhaitez mélanger un jeu de résultats donné.
Notez que le tri d’un grand ensemble de résultats à l’aide d’une fonction ALÉATOIRE peut s’avérer très lent, alors assurez-vous de le faire sur de petits ensembles de résultats.
Si vous devez mélanger un grand jeu de résultats et le limiter par la suite, il est préférable d’utiliser quelque chose comme Oracle
SAMPLE(N)
ouTABLESAMPLE
dans SQL Server ou PostgreSQL au lieu d’une fonction aléatoire dans la clause ORDER BY.
Table de base de données
Supposons que nous développons une application de bureau pour lecteur de musique et que nous avons la table song
suivante dans notre base de données.
La table song
est remplie comme suit:
id | artist | title |
---|---|---|
1 | Miyagi & Эндшпиль ft. Рем Дигга | I Got Love |
2 | HAIM | Don’t Save Me (Cyril Hahn Remix) |
3 | 2Pac ft. DMX | Montée D’Un Champion (GalilHD Remix) |
4 | Ed Sheeran &Passager | Pas de Diggity (Kygo Remix) |
5 | JP Cooper ft. Mali-Koa | Tout cet amour |
En utilisant une fonction ALÉATOIRE dans la clause SQL ORDER BY
Nous voulons mélanger la liste des chansons afin que chaque nouvelle liste de lecture soit différente de celle générée précédemment. Chaque fois que nous devons trier un ensemble de résultats de requête SQL donné, nous devons utiliser la clause ORDER BY.
Cependant, pour randomiser les lignes renvoyées, nous avons besoin de la clause ORDER BY pour utiliser une fonction ou un objet de base de données qui renvoie une valeur aléatoire pour chaque ligne contenue dans le jeu de résultats SQL.
Comme déjà mentionné, l’utilisation d’une fonction spécifique à la base de données qui renvoie des valeurs aléatoires convient uniquement aux petits ensembles de résultats, sinon les performances de la requête SQL vont être affectées. Heureusement, dans notre cas, la table song
représente la liste de lecture actuelle d’une application de bureau, d’où la taille du jeu de résultats est raisonnable.
Oracle
Sur Oracle, vous devez utiliser la fonction DBMS_RANDOM.VALUE
, comme illustré par l’exemple suivant :
SELECT artist||' - '||title AS songFROM songORDER BY DBMS_RANDOM.VALUE
Lors de l’exécution de la requête SQL ci-dessus sur Oracle, l’ensemble de résultats suivant est obtenu:
HAIM – Don’t Save Me (Cyril Hahn Remix)
Ed Sheeran &Passenger -No Diggity (Kygo Remix)
Miyagi &Эндшпиль ft. Рем Дигга – J’ai de l’amour
JP Cooper ft. Mali-Koa – Tout Cet amour
2Pac ft. DMX-Rise Of A Champion (GalilHD Remix)
Notez que les chansons sont listées dans un ordre aléatoire, grâce à l’appel de fonction DBMS_RANDOM.VALUE
utilisé par la clause ORDER BY.
La fonction
VALUE
dans le packageDBMS_RANDOM
renvoie une valeur numérique dans l’intervalle [0, 1) avec une précision de 38 chiffres fractionnaires.
SQL Server
Sur SQL Server, vous devez utiliser la fonction NEWID
, comme illustré par l’exemple suivant :
SELECT CONCAT(CONCAT(artist, ' - '), title) AS songFROM songORDER BY NEWID()
Lors de l’exécution de la requête SQL ci-dessus sur SQL Server, le jeu de résultats suivant est obtenu :
Miyagi &Эндшпиль ft. Рем Дига – J’ai de l’amour
HAIM – Don’t Save Me (Cyril Hahn Remix)
2Pac ft. DMX – Rise Of A Champion (GalilHD Remix)
Ed Sheeran &Passenger -No Diggity (Kygo Remix)
JP Cooper ft. Mali-Koa-All This Love
Notez que les chansons sont listées dans un ordre aléatoire, grâce à l’appel de fonction NEWID()
utilisé par la clause ORDER BY.
La fonction
NEWID
renvoie un type de donnéesuniqueidentifier
représentant un GUID de 16 octets. Par conséquent, chaque nouvelle valeur renvoyée par la fonctionNEWID
sera pratiquement unique.
PostgreSQL
Sur PostgreSQL, vous devez utiliser la fonction random
, comme illustré par l’exemple suivant :
SELECT artist||' - '||title AS songFROM songORDER BY random()
Lors de l’exécution de la requête SQL ci-dessus sur PostgreSQL, le jeu de résultats suivant est obtenu:
JP Cooper ft. Mali-Koa – Tout Cet amour
2Pac ft. DMX – Rise Of A Champion (GalilHD Remix)
HAIM – Don’t Save Me (Cyril Hahn Remix)
Ed Sheeran &Passenger -No Diggity (Kygo Remix)
Miyagi &Эндшпиль ft. Рем Дигга – I Got Love
Notez que les chansons sont listées dans un ordre aléatoire, grâce à l’appel de fonction random()
utilisé par la clause ORDER BY.
La fonction
random
renvoie une valeur numérique dans l’intervalle [0, 1) du typedouble precision
.
MySQL
Sur MySQL, vous devez utiliser la fonction RAND
, comme illustré par l’exemple suivant:
SELECT CONCAT(CONCAT(artist, ' - '), title) AS songFROM songORDER BY RAND()
Lors de l’exécution de la requête SQL ci-dessus sur MySQL, le jeu de résultats suivant est obtenu:
>
2Pac ft. Il S’agit De L’Un Des Plus Grands Succès De L’Histoire De La Musique. Mali-Koa – Tout Cet Amour
Miyagi &Эндшпиль ft. Рем дигга – I Got Love
Ed Sheeran &Passenger –No Diggity (Kygo Remix)
HAIM – Don’t Save Me (Cyril Hahn Remix)
Notez que les chansons sont listées dans un ordre aléatoire, grâce au RAND()
La fonction
RAND
renvoie une valeur numérique dans l’intervalle [0, 1) d’un type à virgule flottante.
JPA et Hibernate
Lorsque vous utilisez des requêtes d’entité JPA et Hibernate, vous pouvez simplement passer la fonction aléatoire à la clause ORDER BY comme illustré par la requête JPQL suivante :
List<Song> songs = entityManager.createQuery( "SELECT s " + "FROM Song s " + "ORDER BY random()", Song.class).getResultList();
La requête JPQL ci-dessus fonctionnera très bien pour PostgreSQL, SQL Server et MySQL car la
random()
, NEWID()
ou RAND()
les fonctions seront transmises par Hibernate telles quelles à l’ORDRE SQL BY.
Pour Oracle, puisque le caractère aléatoire est donné par le générateur de nombres DBMS_RANDOM.VALUE
, vous devrez le référencer comme une fonction SQL (par exemple, DBMS_RANDOM.VALUE()
) :
List<Song> songs = entityManager.createQuery( "SELECT s " + "FROM Song s " + "ORDER BY DBMS_RANDOM.VALUE()", Song.class).getResultList();
C’est tout !
Ateliers en ligne
Si vous avez apprécié cet article, je parie que vous allez adorer mon prochain Atelier en ligne de 4 jours!
- Atelier en ligne de persistance Java haute performance (4 heures x 4 jours) entre le 19 et le 22 avril
Conclusion
La randomisation du jeu de résultats de requêtes SQL est une exigence courante, il est donc utile de savoir ce qui suit : Fonction SQL que vous pouvez utiliser dans la clause ORDER BY en fonction du type de base de données relationnelle sous-jacente.