4 回答

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

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

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