@@ -163,8 +163,27 @@ func (store *Store) LockLedger(ctx context.Context) (*Store, bun.IDB, func() err
163163 }
164164}
165165
166+ // newScopedSelect creates a new select query scoped to the current ledger.
167+ // notes(gfyrag): The "WHERE ledger = 'XXX'" condition can cause degraded postgres plan.
168+ // To avoid that, we use a WHERE OR to separate the two cases:
169+ // 1. Check if the ledger is the only one in the bucket
170+ // 2. Otherwise, filter by ledger name
166171func (store * Store ) newScopedSelect () * bun.SelectQuery {
167- return store .db .NewSelect ().Where ("ledger = ?" , store .ledger .Name )
172+ q := store .db .NewSelect ()
173+ checkLedgerAlone := store .db .NewSelect ().
174+ TableExpr ("_system.ledgers" ).
175+ ColumnExpr ("count = 1" ).
176+ Join ("JOIN (?) AS counters ON _system.ledgers.bucket = counters.bucket" ,
177+ store .db .NewSelect ().
178+ TableExpr ("_system.ledgers" ).
179+ ColumnExpr ("bucket" ).
180+ ColumnExpr ("COUNT(*) AS count" ).
181+ Group ("bucket" ),
182+ ).
183+ Where ("_system.ledgers.name = ?" , store .ledger .Name )
184+
185+ return q .
186+ Where ("((?) or ledger = ?)" , checkLedgerAlone , store .ledger .Name )
168187}
169188
170189func New (db bun.IDB , bucket bucket.Bucket , l ledger.Ledger , opts ... Option ) * Store {
@@ -178,7 +197,7 @@ func New(db bun.IDB, bucket bucket.Bucket, l ledger.Ledger, opts ...Option) *Sto
178197 }
179198
180199 var err error
181- ret .checkBucketSchemaHistogram , err = ret .meter .Int64Histogram ("store.check_bucket_schema" )
200+ ret .checkBucketSchemaHistogram , err = ret .meter .Int64Histogram ("store.check_bucket_schema" )
182201 if err != nil {
183202 panic (err )
184203 }
0 commit comments