[performance] Optimize local timeline + local status count queries (#3892)

* [performance] Optimize local timeline + local status count queries

* remove if not exists from create view
This commit is contained in:
tobi 2025-03-10 13:52:19 +01:00 committed by GitHub
commit 0c72282559
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 251 additions and 32 deletions

View file

@ -77,45 +77,53 @@ func (i *instanceDB) CountInstanceUsers(ctx context.Context, domain string) (int
}
func (i *instanceDB) CountInstanceStatuses(ctx context.Context, domain string) (int, error) {
localhost := (domain == config.GetHost() || domain == config.GetAccountDomain())
local := (domain == config.GetHost() || domain == config.GetAccountDomain())
if localhost {
// Check for a cached instance statuses count, if so return this.
if n := i.state.Caches.DB.LocalInstance.Statuses.Load(); n != nil {
return *n, nil
}
if local {
return i.countLocalStatuses(ctx)
}
q := i.db.
NewSelect().
TableExpr("? AS ?", bun.Ident("statuses"), bun.Ident("status"))
if localhost {
// if the domain is *this* domain, just count where local is true
q = q.Where("? = ?", bun.Ident("status.local"), true)
} else {
// join on the domain of the account
q = q.
Join("JOIN ? AS ? ON ? = ?", bun.Ident("accounts"), bun.Ident("account"), bun.Ident("account.id"), bun.Ident("status.account_id")).
Where("? = ?", bun.Ident("account.domain"), domain)
}
// Ignore statuses that are currently pending approval.
q = q.Where("NOT ? = ?", bun.Ident("status.pending_approval"), true)
// Ignore statuses that are direct messages.
q = q.Where("NOT ? = ?", bun.Ident("status.visibility"), gtsmodel.VisibilityDirect)
TableExpr("? AS ?", bun.Ident("statuses"), bun.Ident("status")).
// Join on the domain of the account.
Join(
"JOIN ? AS ? ON ? = ?",
bun.Ident("accounts"), bun.Ident("account"),
bun.Ident("account.id"), bun.Ident("status.account_id"),
).
Where("? = ?", bun.Ident("account.domain"), domain).
// Ignore pending approval.
Where("? = ?", bun.Ident("status.pending_approval"), false).
// Ignore direct messages.
Where("NOT ? = ?", bun.Ident("status.visibility"), gtsmodel.VisibilityDirect)
count, err := q.Count(ctx)
if err != nil {
return 0, err
}
if localhost {
// Update cached instance statuses account value.
i.state.Caches.DB.LocalInstance.Statuses.Store(&count)
return count, nil
}
func (i *instanceDB) countLocalStatuses(ctx context.Context) (int, error) {
// Check for a cached instance statuses count, if so return this.
if n := i.state.Caches.DB.LocalInstance.Statuses.Load(); n != nil {
return *n, nil
}
// Select from local count view.
var count int
if err := i.db.
NewSelect().
Table("statuses_local_count_view").
Scan(ctx, &count); err != nil {
return 0, err
}
// Update cached instance statuses account value.
i.state.Caches.DB.LocalInstance.Statuses.Store(&count)
return count, nil
}