从大表的JPQL查询中获取随机结果

时间:2016-02-16 11:12:15

标签: sql-server jpa jpql

我目前正在使用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)

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

我已经弄清楚了。在检索播放器时,我还检索了其他未使用的相关实体以及与该实体相关的所有实体,因此也是如此。

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