从大型 table 的 JPQL 查询中获取随机结果
Get random result from JPQL query over large table
我目前正在使用 JPQL 查询从数据库中检索信息。该项目的目的是通过使用不同元素的随机性来测试示例环境,因此我需要查询来检索整个项目中的随机单个结果。
我面临的问题是 JPQL 没有实现适当的随机检索函数,并且随机后计算花费的时间太长(附加函数 return 随机结果需要 14 秒)
public Player getRandomActivePlayerWithTransactions(){
List<Player> randomPlayers = entityManager.createQuery("SELECT pw.playerId FROM PlayerWallet pw JOIN pw.playerId p"
+ " JOIN p.gameAccountCollection ga JOIN ga.iDAccountStatus acs"
+ " WHERE (SELECT count(col.playerWalletTransactionId) FROM pw.playerWalletTransactionCollection col) > 0 AND acs.code = :status")
.setParameter("status", "ACTIVATED")
.getResultList();
return randomPlayers.get(random.nextInt(randomPlayers.size()));
}
由于 JPQL 限制,ORDER BY NEWID() 是不允许的,我测试了以下内联条件,所有这些条件 return 在编译时都出现了语法错误。
WHERE (ABS(CAST((BINARY_CHECKSUM(*) * RAND()) as int)) % 100) < 10
WHERE Rnd % 100 < 10
FROM TABLESAMPLE(10 PERCENT)
您是否考虑过生成随机数并跳至该结果?
我的意思是这样的:
String q = "SELECT COUNT(*) FROM Player p";
Query query=entityManager.createQuery(q);
Number countResult=(Number) query.getSingleResult();
int random = Math.random()*countResult.intValue();
List<Player> randomPlayers = entityManager.createQuery("SELECT pw.playerId FROM PlayerWallet pw JOIN pw.playerId p"
+ " JOIN p.gameAccountCollection ga JOIN ga.iDAccountStatus acs"
+ " WHERE (SELECT count(col.playerWalletTransactionId) FROM pw.playerWalletTransactionCollection col) > 0 AND acs.code = :status")
.setParameter("status", "ACTIVATED")
.setFirstResult(random)
.setMaxResults(1)
.getSingleResult();
我想通了。在检索播放器时,我还检索了其他未使用的相关实体以及与那个等等相关的所有实体。
在向有问题的关系添加 fetch=FetchType.LAZY
(在需要之前不获取实体)之后,查询的性能显着提高。
我目前正在使用 JPQL 查询从数据库中检索信息。该项目的目的是通过使用不同元素的随机性来测试示例环境,因此我需要查询来检索整个项目中的随机单个结果。
我面临的问题是 JPQL 没有实现适当的随机检索函数,并且随机后计算花费的时间太长(附加函数 return 随机结果需要 14 秒)
public Player getRandomActivePlayerWithTransactions(){
List<Player> randomPlayers = entityManager.createQuery("SELECT pw.playerId FROM PlayerWallet pw JOIN pw.playerId p"
+ " JOIN p.gameAccountCollection ga JOIN ga.iDAccountStatus acs"
+ " WHERE (SELECT count(col.playerWalletTransactionId) FROM pw.playerWalletTransactionCollection col) > 0 AND acs.code = :status")
.setParameter("status", "ACTIVATED")
.getResultList();
return randomPlayers.get(random.nextInt(randomPlayers.size()));
}
由于 JPQL 限制,ORDER BY NEWID() 是不允许的,我测试了以下内联条件,所有这些条件 return 在编译时都出现了语法错误。
WHERE (ABS(CAST((BINARY_CHECKSUM(*) * RAND()) as int)) % 100) < 10
WHERE Rnd % 100 < 10
FROM TABLESAMPLE(10 PERCENT)
您是否考虑过生成随机数并跳至该结果? 我的意思是这样的:
String q = "SELECT COUNT(*) FROM Player p";
Query query=entityManager.createQuery(q);
Number countResult=(Number) query.getSingleResult();
int random = Math.random()*countResult.intValue();
List<Player> randomPlayers = entityManager.createQuery("SELECT pw.playerId FROM PlayerWallet pw JOIN pw.playerId p"
+ " JOIN p.gameAccountCollection ga JOIN ga.iDAccountStatus acs"
+ " WHERE (SELECT count(col.playerWalletTransactionId) FROM pw.playerWalletTransactionCollection col) > 0 AND acs.code = :status")
.setParameter("status", "ACTIVATED")
.setFirstResult(random)
.setMaxResults(1)
.getSingleResult();
我想通了。在检索播放器时,我还检索了其他未使用的相关实体以及与那个等等相关的所有实体。
在向有问题的关系添加 fetch=FetchType.LAZY
(在需要之前不获取实体)之后,查询的性能显着提高。