Skip to content

Commit 9c561bc

Browse files
committed
db optimizations. Indexes added
1 parent 6ce836a commit 9c561bc

File tree

2 files changed

+599
-0
lines changed

2 files changed

+599
-0
lines changed

db/pgstorage/migrations/0023.sql

Lines changed: 370 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,370 @@
1+
-- +migrate Up
2+
-- PostgreSQL Index Optimization Migration
3+
-- Purpose: Add missing indexes to improve query performance for zkEVM bridge service
4+
-- Focus areas: Deposits, Claims, Blocks, Exit Roots, Merkle Tree operations
5+
6+
-- ============================================================================
7+
-- SECTION 1: sync.deposit table indexes
8+
-- ============================================================================
9+
10+
-- Index for GetNumberDeposits query: WHERE d.network_id = $1 AND b.block_num <= $2
11+
-- Composite index to support both filtering and joining operations
12+
CREATE INDEX IF NOT EXISTS idx_deposit_network_id_block_id
13+
ON sync.deposit(network_id, block_id);
14+
15+
-- Index for deposit lookup by network and counter: WHERE network_id = $1 AND deposit_cnt = $2
16+
-- Already has a composite filter pattern, adds coverage for frequent lookups
17+
CREATE INDEX IF NOT EXISTS idx_deposit_network_id_deposit_cnt
18+
ON sync.deposit(network_id, deposit_cnt);
19+
20+
-- Index for destination address queries: WHERE dest_addr = $1
21+
-- Used in GetDeposits, GetDepositCount, GetPendingDepositsToClaim
22+
CREATE INDEX IF NOT EXISTS idx_deposit_dest_addr
23+
ON sync.deposit(dest_addr);
24+
25+
-- Index for pending deposits query: WHERE dest_net = $1 AND ready_for_claim = true AND ignore = false
26+
-- Supports GetPendingDepositsToClaim with multiple conditions
27+
CREATE INDEX IF NOT EXISTS idx_deposit_dest_net_ready_ignore
28+
ON sync.deposit(dest_net, ready_for_claim, ignore);
29+
30+
-- Index for deposits ready to claim: WHERE ready_for_claim = true AND dest_net = $1
31+
-- Supports UpdateL1DepositsStatus and UpdateL2DepositsStatus queries
32+
CREATE INDEX IF NOT EXISTS idx_deposit_ready_dest_net
33+
ON sync.deposit(ready_for_claim, dest_net) WHERE ready_for_claim = true;
34+
35+
-- Index for deposit metadata lookups: WHERE network_id = $1 AND orig_addr = $2 AND dest_net = $3
36+
-- Used in GetTokenMetadata
37+
CREATE INDEX IF NOT EXISTS idx_deposit_metadata_lookup
38+
ON sync.deposit(network_id, orig_addr, dest_net) WHERE metadata IS NOT NULL;
39+
40+
-- Index for GetDepositsFromOtherL2ToClaim complex query
41+
-- WHERE network_id != 0 AND ignore = false AND dest_net = $1 AND ready_for_claim = true
42+
CREATE INDEX IF NOT EXISTS idx_deposit_l2_claim_status
43+
ON sync.deposit(dest_net, ready_for_claim, ignore, network_id)
44+
WHERE network_id != 0 AND ignore = false AND ready_for_claim = true;
45+
46+
-- Index for range queries on deposit IDs used in AddRemoveL2GER
47+
-- WHERE id > $1 AND id <= $2 AND network_id = 0 AND dest_net = $3
48+
CREATE INDEX IF NOT EXISTS idx_deposit_id_network_dest
49+
ON sync.deposit(id, network_id, dest_net);
50+
51+
-- Index for original address lookups (used in GetPendingDepositsToClaim with leafType filter)
52+
CREATE INDEX IF NOT EXISTS idx_deposit_orig_addr
53+
ON sync.deposit(orig_addr);
54+
55+
-- ============================================================================
56+
-- SECTION 2: sync.claim table indexes
57+
-- ============================================================================
58+
59+
-- Index for mainnet flag filtering: WHERE mainnet_flag = true AND network_id = $1
60+
CREATE INDEX IF NOT EXISTS idx_claim_mainnet_network
61+
ON sync.claim(mainnet_flag, network_id) WHERE mainnet_flag = true;
62+
63+
-- Index for rollup claim filtering: WHERE NOT mainnet_flag AND rollup_index + 1 = $1 AND network_id = $2
64+
CREATE INDEX IF NOT EXISTS idx_claim_rollup_network
65+
ON sync.claim(rollup_index, network_id) WHERE NOT mainnet_flag;
66+
67+
-- Index for destination address queries: WHERE dest_addr = $1
68+
-- Used in GetClaimCount and GetClaims
69+
CREATE INDEX IF NOT EXISTS idx_claim_dest_addr
70+
ON sync.claim(dest_addr);
71+
72+
-- Index for GetDepositsFromOtherL2ToClaim subquery: WHERE network_id = $1 AND index = ?
73+
-- Supports NOT IN subquery optimization
74+
CREATE INDEX IF NOT EXISTS idx_claim_network_id_index
75+
ON sync.claim(network_id, index);
76+
77+
-- Index for global_index lookups used in DeleteClaimByGlobalIndex
78+
CREATE INDEX IF NOT EXISTS idx_claim_global_index_network
79+
ON sync.claim(global_index, network_id);
80+
81+
-- ============================================================================
82+
-- SECTION 3: sync.block table indexes
83+
-- ============================================================================
84+
85+
-- Index for GetLastBlock and GetPreviousBlock queries
86+
-- WHERE network_id = $1 ORDER BY block_num DESC
87+
CREATE INDEX IF NOT EXISTS idx_block_network_id_block_num_desc
88+
ON sync.block(network_id, block_num DESC);
89+
90+
-- Index for block hash lookups: WHERE block_hash = $1
91+
-- Already covered by UNIQUE constraint block_hash_unique from migration 0004
92+
-- UNIQUE constraints automatically create an index in PostgreSQL
93+
94+
-- Index for block number range queries used in Reset
95+
-- WHERE block_num > $1 AND network_id = $2
96+
CREATE INDEX IF NOT EXISTS idx_block_num_network_id
97+
ON sync.block(block_num, network_id);
98+
99+
-- ============================================================================
100+
-- SECTION 4: sync.exit_root table indexes
101+
-- ============================================================================
102+
103+
-- Index for GetLatestL1SyncedExitRoot query
104+
-- WHERE allowed = true AND block_id > 0 AND network_id = 0 ORDER BY id DESC
105+
CREATE INDEX IF NOT EXISTS idx_exit_root_allowed_blockid_network
106+
ON sync.exit_root(allowed, block_id, network_id, id DESC)
107+
WHERE allowed = true AND block_id > 0;
108+
109+
-- Index for GetLatestTrustedExitRoot query
110+
-- WHERE network_id = $1 AND allowed = true ORDER BY id DESC
111+
CREATE INDEX IF NOT EXISTS idx_exit_root_network_allowed_id_desc
112+
ON sync.exit_root(network_id, allowed, id DESC) WHERE allowed = true;
113+
114+
-- Index for GetL1ExitRootByGER query
115+
-- WHERE allowed = true AND block_id > 0 AND global_exit_root = $1 AND network_id = 0
116+
CREATE INDEX IF NOT EXISTS idx_exit_root_ger_lookup
117+
ON sync.exit_root(global_exit_root, network_id, allowed, block_id)
118+
WHERE allowed = true AND block_id > 0;
119+
120+
-- Index for GetL2ExitRootsByGER query
121+
-- WHERE allowed = true AND block_id > 0 AND global_exit_root = $1 AND network_id != 0
122+
CREATE INDEX IF NOT EXISTS idx_exit_root_l2_ger
123+
ON sync.exit_root(global_exit_root, network_id, allowed, block_id)
124+
WHERE allowed = true AND block_id > 0 AND network_id != 0;
125+
126+
-- Index for exit_roots array queries (used in GetDepositCountByGER)
127+
-- Using GIN index for array containment operations
128+
CREATE INDEX IF NOT EXISTS idx_exit_root_exit_roots_array
129+
ON sync.exit_root USING GIN(exit_roots);
130+
131+
-- Index for UpdateL2GER: WHERE id = $1
132+
-- Already has primary key, but adding for clarity in WHERE clauses
133+
134+
-- Index for GetPreviousGERSQL in AddRemoveL2GER
135+
-- WHERE network_id = $1 AND id < $2 ORDER BY id DESC
136+
CREATE INDEX IF NOT EXISTS idx_exit_root_network_id_desc
137+
ON sync.exit_root(network_id, id DESC);
138+
139+
-- Index for UpdateGERStatusSQL in AddRemoveL2GER
140+
-- WHERE global_exit_root = $1 AND network_id = $2
141+
CREATE INDEX IF NOT EXISTS idx_exit_root_ger_network
142+
ON sync.exit_root(global_exit_root, network_id);
143+
144+
-- ============================================================================
145+
-- SECTION 5: sync.token_wrapped table indexes
146+
-- ============================================================================
147+
148+
-- Index for GetTokenWrapped query: WHERE orig_net = $1 AND orig_token_addr = $2
149+
-- Primary key already exists but adding for WHERE clause performance
150+
CREATE INDEX IF NOT EXISTS idx_token_wrapped_orig_net_addr
151+
ON sync.token_wrapped(orig_net, orig_token_addr);
152+
153+
-- ============================================================================
154+
-- SECTION 6: mt.root table indexes (Merkle Tree)
155+
-- ============================================================================
156+
157+
-- Index for GetDepositCountByRoot: WHERE root = $1 AND network = $2
158+
-- Migration 0002 already created root_network_idx: ON mt.root(root, network)
159+
-- Verified this index exists
160+
161+
-- Index for GetRoot: WHERE deposit_cnt = $1 AND network = $2
162+
-- The query logic maps deposit_cnt to deposit_id via sync.deposit JOIN
163+
-- This index supports lookups by deposit_id and network
164+
CREATE INDEX IF NOT EXISTS idx_root_deposit_id_network
165+
ON mt.root(deposit_id, network);
166+
167+
-- Index for CheckIfRootExists: WHERE root = $1 AND network = $2
168+
-- Already covered by root_network_idx from migration 0002
169+
170+
-- Index for GetLastDepositCount subquery: WHERE network = $1
171+
CREATE INDEX IF NOT EXISTS idx_root_network
172+
ON mt.root(network);
173+
174+
-- ============================================================================
175+
-- SECTION 7: mt.rht table indexes (Reverse Hash Table)
176+
-- ============================================================================
177+
178+
-- Index for Get operation: WHERE key = $1
179+
-- Migration 0003 already created rht_key_idx on (key)
180+
-- The table has a deposit_id column as foreign key to sync.deposit(id)
181+
-- Verified this index exists
182+
183+
-- ============================================================================
184+
-- SECTION 8: mt.rollup_exit table indexes
185+
-- ============================================================================
186+
187+
-- Index for GetRollupExitLeavesByRoot: WHERE root = $1 ORDER BY rollup_id ASC
188+
CREATE INDEX IF NOT EXISTS idx_rollup_exit_root_rollup_id
189+
ON mt.rollup_exit(root, rollup_id);
190+
191+
-- Index for IsRollupExitRoot: WHERE root = $1
192+
CREATE INDEX IF NOT EXISTS idx_rollup_exit_root
193+
ON mt.rollup_exit(root);
194+
195+
-- Index for GetLatestRollupExitLeaves: GROUP BY rollup_id, MAX(id)
196+
-- Index to support grouping and aggregation
197+
CREATE INDEX IF NOT EXISTS idx_rollup_exit_rollup_id_id
198+
ON mt.rollup_exit(rollup_id, id DESC);
199+
200+
-- Index for UpdateL2DepositsStatus subquery: WHERE root = $1 AND rollup_id = $2
201+
-- Already covered by idx_rollup_exit_root_rollup_id above
202+
203+
-- ============================================================================
204+
-- SECTION 9: sync.monitored_txs table indexes
205+
-- ============================================================================
206+
207+
-- Index for GetClaimTxsByStatus query with JOIN
208+
-- WHERE status = ANY($1) AND sync.deposit.dest_net = $2 ORDER BY created_at ASC
209+
CREATE INDEX IF NOT EXISTS idx_monitored_txs_deposit_id
210+
ON sync.monitored_txs(deposit_id);
211+
212+
-- Index for status filtering: WHERE status = ANY($1)
213+
CREATE INDEX IF NOT EXISTS idx_monitored_txs_status_created
214+
ON sync.monitored_txs(status, created_at);
215+
216+
-- Index for AddClaimTx: ON CONFLICT (deposit_id) DO NOTHING
217+
-- Already has deposit_id as primary key
218+
219+
-- Index for UpdateClaimTx: WHERE deposit_id = $1
220+
-- Already covered by primary key
221+
222+
-- Index for group_id lookups
223+
CREATE INDEX IF NOT EXISTS idx_monitored_txs_group_id
224+
ON sync.monitored_txs(group_id) WHERE group_id IS NOT NULL;
225+
226+
-- ============================================================================
227+
-- SECTION 10: sync.remove_exit_root table indexes
228+
-- ============================================================================
229+
230+
-- Index for potential lookups by global_exit_root and network_id
231+
CREATE INDEX IF NOT EXISTS idx_remove_exit_root_ger_network
232+
ON sync.remove_exit_root(global_exit_root, network_id);
233+
234+
-- Index for block_id references
235+
CREATE INDEX IF NOT EXISTS idx_remove_exit_root_block_id
236+
ON sync.remove_exit_root(block_id);
237+
238+
-- ============================================================================
239+
-- SECTION 11: sync.backward_let table indexes
240+
-- ============================================================================
241+
242+
-- Index for potential lookups by roots and deposit counts
243+
CREATE INDEX IF NOT EXISTS idx_backward_let_new_root
244+
ON sync.backward_let(new_root);
245+
246+
CREATE INDEX IF NOT EXISTS idx_backward_let_previous_root
247+
ON sync.backward_let(previous_root);
248+
249+
-- Index for block_id for reorg operations
250+
CREATE INDEX IF NOT EXISTS idx_backward_let_block_id
251+
ON sync.backward_let(block_id);
252+
253+
-- ============================================================================
254+
-- SECTION 12: sync.forward_let table indexes
255+
-- ============================================================================
256+
257+
-- Index for forward LET lookups by roots
258+
CREATE INDEX IF NOT EXISTS idx_forward_let_new_root
259+
ON sync.forward_let(new_root);
260+
261+
CREATE INDEX IF NOT EXISTS idx_forward_let_previous_root
262+
ON sync.forward_let(previous_root);
263+
264+
-- Index for block_id for reorg operations
265+
CREATE INDEX IF NOT EXISTS idx_forward_let_block_id
266+
ON sync.forward_let(block_id);
267+
268+
-- ============================================================================
269+
-- SECTION 13: sync.set_unset_claim table indexes
270+
-- ============================================================================
271+
272+
-- Index for potential lookups by index, rollup_index, network operations
273+
CREATE INDEX IF NOT EXISTS idx_set_unset_claim_index_rollup
274+
ON sync.set_unset_claim(index, rollup_index, mainnet_flag);
275+
276+
-- Index for global_index lookups
277+
CREATE INDEX IF NOT EXISTS idx_set_unset_claim_global_index
278+
ON sync.set_unset_claim(global_index);
279+
280+
-- Index for type filtering (SET vs UNSET)
281+
CREATE INDEX IF NOT EXISTS idx_set_unset_claim_type
282+
ON sync.set_unset_claim(type);
283+
284+
-- Index for block_id for reorg operations
285+
CREATE INDEX IF NOT EXISTS idx_set_unset_claim_block_id
286+
ON sync.set_unset_claim(block_id);
287+
288+
-- ============================================================================
289+
-- SECTION 14: sync.deposit_backup table indexes
290+
-- ============================================================================
291+
292+
-- Index for deposit_cnt ordering (used in ResetDeposits and GetAndDeleteOrphanDepositBackups)
293+
CREATE INDEX IF NOT EXISTS idx_deposit_backup_deposit_cnt
294+
ON sync.deposit_backup(deposit_cnt);
295+
296+
-- Index for network_id filtering
297+
CREATE INDEX IF NOT EXISTS idx_deposit_backup_network_id
298+
ON sync.deposit_backup(network_id);
299+
300+
-- Note: idx_deposit_backup_backward_let_id already exists from migration 0022
301+
302+
-- ============================================================================
303+
-- SECTION 15: sync.status table indexes
304+
-- ============================================================================
305+
306+
-- Index for GetSyncStatus: ORDER BY network_id ASC
307+
-- Primary key already exists on network_id
308+
-- Verified coverage
309+
310+
-- +migrate Down
311+
312+
-- Remove all indexes created in this migration
313+
DROP INDEX IF EXISTS sync.idx_deposit_network_id_block_id;
314+
DROP INDEX IF EXISTS sync.idx_deposit_network_id_deposit_cnt;
315+
DROP INDEX IF EXISTS sync.idx_deposit_dest_addr;
316+
DROP INDEX IF EXISTS sync.idx_deposit_dest_net_ready_ignore;
317+
DROP INDEX IF EXISTS sync.idx_deposit_ready_dest_net;
318+
DROP INDEX IF EXISTS sync.idx_deposit_metadata_lookup;
319+
DROP INDEX IF EXISTS sync.idx_deposit_l2_claim_status;
320+
DROP INDEX IF EXISTS sync.idx_deposit_id_network_dest;
321+
DROP INDEX IF EXISTS sync.idx_deposit_orig_addr;
322+
323+
DROP INDEX IF EXISTS sync.idx_claim_mainnet_network;
324+
DROP INDEX IF EXISTS sync.idx_claim_rollup_network;
325+
DROP INDEX IF EXISTS sync.idx_claim_dest_addr;
326+
DROP INDEX IF EXISTS sync.idx_claim_network_id_index;
327+
DROP INDEX IF EXISTS sync.idx_claim_global_index_network;
328+
329+
DROP INDEX IF EXISTS sync.idx_block_network_id_block_num_desc;
330+
DROP INDEX IF EXISTS sync.idx_block_num_network_id;
331+
332+
DROP INDEX IF EXISTS sync.idx_exit_root_allowed_blockid_network;
333+
DROP INDEX IF EXISTS sync.idx_exit_root_network_allowed_id_desc;
334+
DROP INDEX IF EXISTS sync.idx_exit_root_ger_lookup;
335+
DROP INDEX IF EXISTS sync.idx_exit_root_l2_ger;
336+
DROP INDEX IF EXISTS sync.idx_exit_root_exit_roots_array;
337+
DROP INDEX IF EXISTS sync.idx_exit_root_network_id_desc;
338+
DROP INDEX IF EXISTS sync.idx_exit_root_ger_network;
339+
340+
DROP INDEX IF EXISTS sync.idx_token_wrapped_orig_net_addr;
341+
342+
DROP INDEX IF EXISTS mt.idx_root_deposit_id_network;
343+
DROP INDEX IF EXISTS mt.idx_root_network;
344+
345+
DROP INDEX IF EXISTS mt.idx_rollup_exit_root_rollup_id;
346+
DROP INDEX IF EXISTS mt.idx_rollup_exit_root;
347+
DROP INDEX IF EXISTS mt.idx_rollup_exit_rollup_id_id;
348+
349+
DROP INDEX IF EXISTS sync.idx_monitored_txs_deposit_id;
350+
DROP INDEX IF EXISTS sync.idx_monitored_txs_status_created;
351+
DROP INDEX IF EXISTS sync.idx_monitored_txs_group_id;
352+
353+
DROP INDEX IF EXISTS sync.idx_remove_exit_root_ger_network;
354+
DROP INDEX IF EXISTS sync.idx_remove_exit_root_block_id;
355+
356+
DROP INDEX IF EXISTS sync.idx_backward_let_new_root;
357+
DROP INDEX IF EXISTS sync.idx_backward_let_previous_root;
358+
DROP INDEX IF EXISTS sync.idx_backward_let_block_id;
359+
360+
DROP INDEX IF EXISTS sync.idx_forward_let_new_root;
361+
DROP INDEX IF EXISTS sync.idx_forward_let_previous_root;
362+
DROP INDEX IF EXISTS sync.idx_forward_let_block_id;
363+
364+
DROP INDEX IF EXISTS sync.idx_set_unset_claim_index_rollup;
365+
DROP INDEX IF EXISTS sync.idx_set_unset_claim_global_index;
366+
DROP INDEX IF EXISTS sync.idx_set_unset_claim_type;
367+
DROP INDEX IF EXISTS sync.idx_set_unset_claim_block_id;
368+
369+
DROP INDEX IF EXISTS sync.idx_deposit_backup_deposit_cnt;
370+
DROP INDEX IF EXISTS sync.idx_deposit_backup_network_id;

0 commit comments

Comments
 (0)