4 回答

TA貢獻1821條經(jīng)驗 獲得超5個贊
我并不完全熟悉 Kotlin 語言,但我會用 Java 寫出邏輯,希望它能很好地為您翻譯。
你的目標(biāo)是獲取 20 個單一性別,但在獲取它之前你無法弄清楚它是什么性別。因為我們已經(jīng)從數(shù)據(jù)庫中獲取了 20 行,所以我們可以獲取更多作為備用。
我們可以使用累積分布來計算我們實際需要的行數(shù),使用這個工具:https://stattrek.com/online-calculator/binomial.aspx
假設(shè) 50/50 性別細(xì)分,概率為 0.5。如果您的性別分布與您的需求不同,您可以調(diào)整此項。如果性別細(xì)分不是 50/50,您可以為每個性別創(chuàng)建單獨的桶提取以獲得適當(dāng)?shù)某晒λ?。我們希望至少?20 場成功的比賽。
樣本大小為 60,我們有99.6% 的概率有 20 次或更多的性別匹配。
所以我們可以獲取 60 個而不是 20 個,篩選出所選性別的前 20 個。如果我們沒有達到 20(0.4% 的機會),則重新繪制另一組 20 來填充我們的組。所以 99% 的時間,60 行提取,在一個壞的情況下,可能是 80 行提取。這消除了在應(yīng)該適用于超大型數(shù)據(jù)庫的數(shù)據(jù)庫端使用 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條經(jīng)驗 獲得超10個贊
在你的條件下選擇10萬個id.內(nèi)存中大約幾MB的數(shù)據(jù).just shuffle it.thenselect * from tables in(id1,id2...,id20)

TA貢獻1851條經(jīng)驗 獲得超5個贊
在您的帖子中使用查詢的物化視圖怎么樣。它可以安排在您選擇的時間表刷新(使用 cron 作業(yè)或 Postgres 提供的其他工具)

TA貢獻1829條經(jīng)驗 獲得超6個贊
不要生成 id,而是生成行索引。
然后在一個循環(huán)中你可以這樣做
select top 1 start at :randomBase *
from users where gender = :gender
添加回答
舉報