Fix random_projects route not returning the requested number of projects (#3758)
* Fix random_projects route not returning the requested number of projects * fix(labrinth): further improve random project route SQL query * chore: fix typo in comment * tweak(labrinth): more apparent and fast randomness for `random_projects_get` * tweak(labrinth): even better random projects query * chore: address formatting review --------- Co-authored-by: Alejandro González <me@alegon.dev>
This commit is contained in:
parent
3489771d2e
commit
06f1df1995
@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"db_name": "PostgreSQL",
|
|
||||||
"query": "\n SELECT id FROM mods TABLESAMPLE SYSTEM_ROWS($1) WHERE status = ANY($2)\n ",
|
|
||||||
"describe": {
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"ordinal": 0,
|
|
||||||
"name": "id",
|
|
||||||
"type_info": "Int8"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"parameters": {
|
|
||||||
"Left": [
|
|
||||||
"Int8",
|
|
||||||
"TextArray"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"nullable": [
|
|
||||||
false
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hash": "1cefe4924d3c1f491739858ce844a22903d2dbe26f255219299f1833a10ce3d7"
|
|
||||||
}
|
|
23
apps/labrinth/.sqlx/query-1d017ac5f5b1e76ec241533fd4d061c79f4e6d2f1701e727a7474fd5029a5492.json
generated
Normal file
23
apps/labrinth/.sqlx/query-1d017ac5f5b1e76ec241533fd4d061c79f4e6d2f1701e727a7474fd5029a5492.json
generated
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"db_name": "PostgreSQL",
|
||||||
|
"query": "SELECT id FROM mods WHERE status = ANY($1)\n ORDER BY id\n LIMIT $2\n OFFSET GREATEST(ROUND(RANDOM() * (SELECT COUNT(*) FROM mods WHERE status = ANY($1)))::int8 - $2, 0)",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"ordinal": 0,
|
||||||
|
"name": "id",
|
||||||
|
"type_info": "Int8"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Left": [
|
||||||
|
"TextArray",
|
||||||
|
"Int8"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "1d017ac5f5b1e76ec241533fd4d061c79f4e6d2f1701e727a7474fd5029a5492"
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
-- This index substantially brings down the cost of the query plan for the
|
||||||
|
-- hot query at `labrinth::routes::v3::projects::random_projects_get`, from
|
||||||
|
-- 354.04..363.39 to 171.33..180.68 (~2x improvement).
|
||||||
|
--
|
||||||
|
-- The numbers above were calculated in a clean PostgreSQL 17.5.0 container
|
||||||
|
-- with 10k mods created with the SQL below.
|
||||||
|
--
|
||||||
|
-- WITH seq AS (SELECT n FROM GENERATE_SERIES(1, 10000) AS n)
|
||||||
|
-- INSERT INTO mods (id, team_id, name, summary, icon_url, license_url, slug, status)
|
||||||
|
-- SELECT n, 1, n, '', '', '', n, (ARRAY['approved', 'pending'])[n % 2 + 1] from seq;
|
||||||
|
|
||||||
|
CREATE INDEX mods_status ON mods(status);
|
@ -94,14 +94,17 @@ pub async fn random_projects_get(
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
let project_ids = sqlx::query!(
|
let project_ids = sqlx::query!(
|
||||||
"
|
// IDs are randomly generated (see the `generate_ids` macro), so ID order is
|
||||||
SELECT id FROM mods TABLESAMPLE SYSTEM_ROWS($1) WHERE status = ANY($2)
|
// equivalent to a random order
|
||||||
",
|
"SELECT id FROM mods WHERE status = ANY($1)
|
||||||
count.count as i32,
|
ORDER BY id
|
||||||
|
LIMIT $2
|
||||||
|
OFFSET GREATEST(ROUND(RANDOM() * (SELECT COUNT(*) FROM mods WHERE status = ANY($1)))::int8 - $2, 0)",
|
||||||
&*crate::models::projects::ProjectStatus::iterator()
|
&*crate::models::projects::ProjectStatus::iterator()
|
||||||
.filter(|x| x.is_searchable())
|
.filter(|x| x.is_searchable())
|
||||||
.map(|x| x.to_string())
|
.map(|x| x.to_string())
|
||||||
.collect::<Vec<String>>(),
|
.collect::<Vec<String>>(),
|
||||||
|
count.count as i32,
|
||||||
)
|
)
|
||||||
.fetch(&**pool)
|
.fetch(&**pool)
|
||||||
.map_ok(|m| db_ids::DBProjectId(m.id))
|
.map_ok(|m| db_ids::DBProjectId(m.id))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user