Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Optimizador de hipersistência é essa ferramenta!
introdução
neste artigo, vamos ver como podemos classificar um conjunto de resultados de consulta SQL usando uma ordem por cláusula que toma uma função aleatória fornecida por uma função específica de base de dados.
Este é um truque muito útil, especialmente quando você quer baralhar um determinado conjunto de resultados.
Note que a ordenação de um conjunto de resultados Grande usando uma função aleatória pode revelar-se muito lenta, por isso certifique-se que o faz em pequenos conjuntos de resultados.
Se você tem a embaralhar um grande conjunto de resultados e limitar-la depois, então é melhor usar algo como o Oracle
SAMPLE(N)
ouTABLESAMPLE
no SQL Server ou PostgreSQL em vez de uma função aleatória na cláusula ORDER BY.
Database table
vamos assumir que estamos a desenvolver uma aplicação para Leitor de música, e temos o seguinte song
table in our database.
song
tabela é preenchida da seguinte forma:
id | artist | title |
---|---|---|
1 | Miyagi & Эндшпиль ft. Рем Дигга | I Got Love |
2 | HAIM | Don’t Save Me (Cyril Hahn Remix) |
3 | 2Pac ft. DMX | Ascensão De Um Campeão (GalilHD Remix) |
4 | Ed Sheeran & Passageiro | Não Diggity (Kygo Remix) |
5 | JP Cooper pés. Mali-Koa | todo este amor |
usando uma função aleatória na ordem SQL pela cláusula
queremos baralhar a lista de músicas para que cada nova lista seja diferente da previamente gerada. Sempre que precisamos classificar um determinado conjunto de resultados de consulta SQL, temos que usar a ordem por cláusula.
no entanto, para aleatorizar as linhas devolvidas, precisamos da ordem por cláusula para usar uma função ou objeto de banco de dados que retorna um valor aleatório para cada linha contida no conjunto de resultados SQL.
Como já mencionado, usando uma função específica de banco de dados que retorna valores aleatórios é adequado apenas para pequenos conjuntos de resultados, caso contrário, o desempenho da consulta SQL vai ser afetado. Felizmente, em nosso caso, a tabela song
representa a lista de reprodução atual de uma aplicação desktop, portanto o tamanho do conjunto de resultados é razoável.
Oracle
No Oracle, você precisa usar o DBMS_RANDOM.VALUE
função, como ilustrado pelo exemplo a seguir:
SELECT artist||' - '||title AS songFROM songORDER BY DBMS_RANDOM.VALUE
Ao executar a consulta SQL acima da Oracle, o seguinte conjunto de resultados obtidos:
HAIM – não Me Salvar (Cyril Hahn Remix)
Ed Sheeran & de Passageiros – No Diggity (Kygo Remix)
Miyagi & Эндшпиль pés. Рем дига-I Got Love
JP Cooper ft. Mali-Koa-All This Love
2pac ft. DMX-Rise Of A Champion (GalilHD Remix)
Notice that the songs are being listed in random order, thanks to the DBMS_RANDOM.VALUE
function call used by the ORDER BY clause.
VALUE
funçãoDBMS_RANDOM
pacote retorna um valor numérico em [0, 1) intervalo com uma precisão de 38 dígitos fracionários.
o SQL Server
No SQL Server, você precisará usar NEWID
função, como ilustrado pelo exemplo a seguir:
SELECT CONCAT(CONCAT(artist, ' - '), title) AS songFROM songORDER BY NEWID()
Ao executar a consulta SQL acima no SQL Server, o seguinte conjunto de resultados obtidos:
Miyagi & Эндшпиль pés. Рем дига-I Got Love
HAIM-Don’t Save Me (Cyril Hahn Remix)
2pac ft. DMX – Ascensão De Um Campeão (GalilHD Remix)
Ed Sheeran & de Passageiros – No Diggity (Kygo Remix)
JP Cooper pés. Mali-Koa-All This Love
Notice that the songs are being listed in random order, thanks to the NEWID()
function call used by the ORDER BY clause.
NEWID
função retorna umuniqueidentifier
tipo de dados que representa um GUID de 16 bytes. Assim, cada novo valor retornado pela funçãoNEWID
vai ser virtualmente único.
o PostgreSQL
No PostgreSQL, você precisa usar o random
função, como ilustrado pelo exemplo a seguir:
SELECT artist||' - '||title AS songFROM songORDER BY random()
Ao executar a consulta SQL acima sobre o PostgreSQL, o seguinte conjunto de resultados obtidos:
JP Cooper pés. Mali-Koa-All This Love
2pac ft. DMX – Ascensão De Um Campeão (GalilHD Remix)
HAIM – não Me Salvar (Cyril Hahn Remix)
Ed Sheeran & de Passageiros – No Diggity (Kygo Remix)
Miyagi & Эндшпиль pés. Рем дига-I Got Love
Notice that the songs are being listed in random order, thanks to the random()
function call used by the ORDER BY clause.
a função
random
devolve um valor numérico no intervalo [0, 1) dodouble precision
tipo.
MySQL
No MySQL, você precisará usar RAND
função, como ilustrado pelo exemplo a seguir:
SELECT CONCAT(CONCAT(artist, ' - '), title) AS songFROM songORDER BY RAND()
Ao executar a consulta SQL acima no MySQL, o seguinte conjunto de resultados obtidos:
2Pac pés. DMX-Rise Of A Champion (GalilHD Remix)
JP Cooper ft. Mali-Koa-All This Love
Miyagi & Эндшпиль ft. Рем Дигга – eu Tenho Amor
Ed Sheeran & de Passageiros – No Diggity (Kygo Remix)
HAIM – não Me Salvar (Cyril Hahn Remix)
Observe que as músicas estão sendo listados em ordem aleatória, graças ao RAND()
chamada de função usado pela cláusula ORDER by.
o
RAND
função devolve um valor numérico no intervalo [0, 1) de um tipo de vírgula flutuante.
JPA e Hibernate
Quando usando JPA e Hibernate consultas de entidade, você pode passar apenas a função de reprodução aleatória para a cláusula ORDER BY como ilustrado pelo seguinte consulta JPQL:
List<Song> songs = entityManager.createQuery( "SELECT s " + "FROM Song s " + "ORDER BY random()", Song.class).getResultList();
A JPQL consulta acima irá funcionar muito bem para o PostgreSQL, SQL Server, e o MySQL, pois o random()
NEWID()
ou RAND()
funções serão passados pelo Hibernate como o SQL ORDER BY.
Para Oracle, uma vez que a aleatoriedade é dada por DBMS_RANDOM.VALUE
gerador de números, você terá de fazer referência a ela como uma função SQL (por exemplo, DBMS_RANDOM.VALUE()
):
List<Song> songs = entityManager.createQuery( "SELECT s " + "FROM Song s " + "ORDER BY DBMS_RANDOM.VALUE()", Song.class).getResultList();
é isso aí!
Workshops Online
If you enjoyed this article, I bet you are going to love my upcoming 4-day Online Workshop!
- de Alta Performance em Java Persistence On-line Workshop (4 horas x 4 dias) entre os dias 19 e 22 de abril
Conclusão
Randomizar a consulta SQL conjunto de resultados é um requisito comum, portanto, é útil para saber o que o SQL função que você pode usar a cláusula ORDER BY, dependendo do banco de dados relacional subjacente tipo.