【问题标题】:Get random result from JPQL query over large table从大表上的 JPQL 查询中获取随机结果
【发布时间】:2016-05-27 15:21:48
【问题描述】:

我目前正在使用 JPQL 查询从数据库中检索信息。该项目的目的是通过具有不同元素的随机性来测试示例环境,因此我需要查询来检索整个项目中的随机单个结果。

我面临 JPQL 没有为随机检索实现适当的函数,并且随机后计算需要太长时间(附加函数返回随机结果需要 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(),我测试了以下内联条件,所有这些条件在编译时都返回语法错误。

WHERE (ABS(CAST((BINARY_CHECKSUM(*) * RAND()) as int)) % 100) < 10
WHERE Rnd % 100 < 10  
FROM TABLESAMPLE(10 PERCENT)

【问题讨论】:

标签: sql-server jpa jpql


【解决方案1】:

您是否考虑过生成一个随机数并跳到该结果? 我的意思是这样的:

        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();

【讨论】:

  • 我考虑过但是查询返回的结果是所有玩家的子集,所以随机计数器可以从子集中生成一个结果标识符。
  • 所以使用相同的查询进行计数:“SELECT count(pw.playerId) ...”如果不是太重的话...
  • 那东西太重了。
【解决方案2】:

我想通了。在检索玩家时,我也在检索其他未使用的相关实体以及与该玩家相关的所有实体等等。

将fetch=FetchType.LAZY(在需要之前不要获取实体)添加到有问题的关系后,查询的性能显着提高。

【讨论】:

    猜你喜欢
    • 2012-09-03
    • 2011-03-30
    • 2018-03-13
    • 1970-01-01
    • 2010-10-18
    • 2019-02-17
    • 1970-01-01
    • 2016-11-26
    • 1970-01-01
    相关资源
    最近更新 更多