4 回答
 
                    
                    TA贡献1821条经验 获得超5个赞
我并不完全熟悉 Kotlin 语言,但我会用 Java 写出逻辑,希望它能很好地为您翻译。
你的目标是获取 20 个单一性别,但在获取它之前你无法弄清楚它是什么性别。因为我们已经从数据库中获取了 20 行,所以我们可以获取更多作为备用。
我们可以使用累积分布来计算我们实际需要的行数,使用这个工具:https://stattrek.com/online-calculator/binomial.aspx
假设 50/50 性别细分,概率为 0.5。如果您的性别分布与您的需求不同,您可以调整此项。如果性别细分不是 50/50,您可以为每个性别创建单独的桶提取以获得适当的成功水平。我们希望至少有 20 场成功的比赛。
样本大小为 60,我们有99.6% 的概率有 20 次或更多的性别匹配。
所以我们可以获取 60 个而不是 20 个,筛选出所选性别的前 20 个。如果我们没有达到 20(0.4% 的机会),则重新绘制另一组 20 来填充我们的组。所以 99% 的时间,60 行提取,在一个坏的情况下,可能是 80 行提取。这消除了在应该适用于超大型数据库的数据库端使用 RAND 的情况。
Set<Long> idsToFetch = random.longs(2*amountOfIds, 1L, numberOfUsersInDatabase)
.boxed()
.filter { num -> !excludedIds.contains(num) }
.limit(amountOfIds * 3)
.collect(toSet());
List<User> randomUsers = userRepository.findUsersByIds(idsToFetch);
List<User> selectedUsers = randomUsers
.stream()
.filter(e -> e.gender == selectedGender)
.limit(amountOfIds)
.collect(toList());
if(selectedUsers.length < amountOfIds) {
//redo or single fetch operation
}
 
                    
                    TA贡献1796条经验 获得超10个赞
在你的条件下选择10万个id.内存中大约几MB的数据.just shuffle it.thenselect * from tables in(id1,id2...,id20)
 
                    
                    TA贡献1829条经验 获得超6个赞
不要生成 id,而是生成行索引。
然后在一个循环中你可以这样做
select top 1 start at :randomBase *
from users where gender = :gender
添加回答
举报

