Analyse entries once when entries_recent has no statistics (#274)

Deployed, the judge's query still read every entry: an expression index
has no statistics until its table is analysed, and Postgres, guessing a
third of entries were recent, chose a scan (898 ms) over entries_recent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-17 14:17:56 +00:00
parent 2077ea5810
commit 5130f754cc

View File

@@ -117,6 +117,15 @@ async fn create_missing(orm: &sea_orm::DatabaseConnection) -> Result<()> {
orm.execute_unprepared(sql).await.with_context(|| sql.to_owned())?;
}
}
// An expression index has no statistics until its table is analysed, and without them
// Postgres guessed a third of entries were recent and read them all, entries_recent unused
// (#274). Analysed once when they are missing; autovacuum keeps them after.
if orm.get_database_backend() == sea_orm::DbBackend::Postgres {
let has = Statement::from_string(sea_orm::DbBackend::Postgres, "SELECT 1 FROM pg_stats WHERE tablename = 'entries_recent'");
if orm.query_one_raw(has).await?.is_none() {
orm.execute_unprepared("ANALYZE entries").await.context("analysing entries")?;
}
}
if orm.execute_unprepared("SELECT recheck FROM signal_verdicts LIMIT 0").await.is_err() {
let sql = "ALTER TABLE signal_verdicts ADD COLUMN recheck BOOLEAN NOT NULL DEFAULT false";
orm.execute_unprepared(sql).await.with_context(|| sql.to_owned())?;