From 68f68953d1630bcc04599c9697049e72912cf491 Mon Sep 17 00:00:00 2001 From: Evan Date: Thu, 2 Jul 2026 12:05:47 +0800 Subject: [PATCH] perf(ttx): index transactions by sender_eid/recipient_eid + stored_at QueryTransactions filters (sender_eid = X OR recipient_eid = Y) ORDER BY stored_at LIMIT N, but the transactions table is only indexed on tx_id and stored_at. Without an index on sender_eid/recipient_eid the planner walks the entire stored_at index applying the filter row by row (~11M rows scanned to return a handful for a low-activity wallet, ~2.6s in our deployment). Add (sender_eid, stored_at DESC) and (recipient_eid, stored_at DESC) so it can BitmapOr the two and apply the limit cheaply (~1ms). Refs #1841 Signed-off-by: Evan --- token/services/storage/db/sql/common/transactions.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/token/services/storage/db/sql/common/transactions.go b/token/services/storage/db/sql/common/transactions.go index 16874bb2fc..4bf15bdf5c 100644 --- a/token/services/storage/db/sql/common/transactions.go +++ b/token/services/storage/db/sql/common/transactions.go @@ -461,6 +461,8 @@ func (db *TransactionStore) GetSchema() string { ); CREATE INDEX IF NOT EXISTS idx_tx_id_%s ON %s ( tx_id ); CREATE INDEX IF NOT EXISTS idx_storedat_%s ON %s ( stored_at DESC ); + CREATE INDEX IF NOT EXISTS idx_sender_eid_storedat_%s ON %s ( sender_eid, stored_at DESC ); + CREATE INDEX IF NOT EXISTS idx_recipient_eid_storedat_%s ON %s ( recipient_eid, stored_at DESC ); -- movements CREATE TABLE IF NOT EXISTS %s ( @@ -485,7 +487,7 @@ func (db *TransactionStore) GetSchema() string { CREATE INDEX IF NOT EXISTS idx_tx_id_%s ON %s ( tx_id ); `, db.table.Requests, db.table.Requests, db.table.Requests, db.table.Requests, db.table.Requests, - db.table.Transactions, db.table.Requests, db.table.Transactions, db.table.Transactions, db.table.Transactions, db.table.Transactions, + db.table.Transactions, db.table.Requests, db.table.Transactions, db.table.Transactions, db.table.Transactions, db.table.Transactions, db.table.Transactions, db.table.Transactions, db.table.Transactions, db.table.Transactions, db.table.Movements, db.table.Requests, db.table.Movements, db.table.Movements, db.table.Movements, db.table.Movements, db.table.TransactionEndorseAck, db.table.TransactionEndorseAck, db.table.TransactionEndorseAck, )