@@ -338,28 +338,31 @@ impl<'conn> SynapseReader<'conn> {
338
338
///
339
339
/// - An underlying database error
340
340
pub async fn count_rows ( & mut self ) -> Result < SynapseRowCounts , Error > {
341
+ // We don't get to filter out application service users by using this estimate,
342
+ // which is a shame, but on a large database this is way faster.
343
+ // On matrix.org, counting users and devices properly takes around 1m10s,
344
+ // which is unnecessary extra downtime during the migration, just to
345
+ // show a more accurate progress bar and size a hash map accurately.
341
346
let users: usize = sqlx:: query_scalar :: < _ , i64 > (
342
347
"
343
- SELECT COUNT(1) FROM users
344
- WHERE appservice_id IS NULL
348
+ SELECT reltuples::bigint AS estimate FROM pg_class WHERE oid = 'users'::regclass;
345
349
" ,
346
350
)
347
351
. fetch_one ( & mut * self . txn )
348
352
. await
349
- . into_database ( "counting Synapse users" ) ?
353
+ . into_database ( "estimating count of users" ) ?
350
354
. max ( 0 )
351
355
. try_into ( )
352
356
. unwrap_or ( usize:: MAX ) ;
353
357
354
358
let devices = sqlx:: query_scalar :: < _ , i64 > (
355
359
"
356
- SELECT COUNT(1) FROM devices
357
- WHERE NOT hidden
360
+ SELECT reltuples::bigint AS estimate FROM pg_class WHERE oid = 'devices'::regclass;
358
361
" ,
359
362
)
360
363
. fetch_one ( & mut * self . txn )
361
364
. await
362
- . into_database ( "counting Synapse devices" ) ?
365
+ . into_database ( "estimating count of devices" ) ?
363
366
. max ( 0 )
364
367
. try_into ( )
365
368
. unwrap_or ( usize:: MAX ) ;
0 commit comments