Skip to content

Commit 1900a88

Browse files
committed
Clean db indexes
- Swap wrong index names `history_decoded_not_proc_idx` and `history_decoded_processed_idx` - Remove not used indexes The following indexes have been identified as unused (0 scans) and are being removed to reduce database size: | Index Name | Mainnet DB Size | Polygon DB Size | Usage Status | Justification | |------------|----------------|-----------------|--------------|---------------| | `history_ethereumtx_to_9fb37c13` | 1588 MB | 9893 MB | 0 scans | Unused - no queries filter by `to` field | | `history_ethereumtx__from_e36d4662` | 1758 MB | 8707 MB | 0 scans | Unused - no queries filter by `_from` field | | `history_ethereumtx_status_d1d0de2c` | 1074 MB | 6645 MB | 0 scans | Unused - no queries filter by `status` field | | `history_internaltxdecoded_function_name_333ae03e` | 519 MB | 3204 MB | 0 scans (DB1) / 69K scans (DB2) | Replaced by dedicated `history_decoded_setup_idx` for `function_name="setup"` queries | | `history_internaltxdecoded_function_name_333ae03e_like` | 519 MB | 3205 MB | 0 scans | Unused - no LIKE queries on `function_name` | | `history_multisigtransaction_failed_4842ad6b` | 43 MB | N/A | 0 scans | Unused - field is used but index is not needed | | `history_decoded_setup_idx` | 13 MB | 194 MB | 0 scans (DB1) / 62K scans (DB2) | **KEEPING** - Used in DB2, will monitor DB1 | | `history_safe_banned_idx` | 8 KB | N/A | 0 scans | Unused - no queries filter by `banned=True` | **Total Potential Savings:** - Database 1: ~5.5 GB - Database 2: ~28.5 GB **Note:** The `function_name` indexes are being removed because: - The dedicated `history_decoded_setup_idx` (partial index on `safe_address` WHERE `function_name="setup"`) covers the only production query that filters by `function_name` - Admin interface filtering does not require these indexes for performance - All other `function_name` queries are in tests or already-executed migrations
1 parent b89b695 commit 1900a88

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Generated by Django 5.2.9 on 2025-12-10 13:18
2+
3+
import safe_eth.eth.django.models
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('history', '0098_internaltxdecoded_setup_idx'),
11+
]
12+
13+
operations = [
14+
migrations.AlterField(
15+
model_name='ethereumtx',
16+
name='_from',
17+
field=safe_eth.eth.django.models.EthereumAddressBinaryField(null=True),
18+
),
19+
migrations.AlterField(
20+
model_name='ethereumtx',
21+
name='status',
22+
field=models.IntegerField(default=None, null=True),
23+
),
24+
migrations.AlterField(
25+
model_name='ethereumtx',
26+
name='to',
27+
field=safe_eth.eth.django.models.EthereumAddressBinaryField(null=True),
28+
),
29+
migrations.AlterField(
30+
model_name='internaltxdecoded',
31+
name='function_name',
32+
field=models.CharField(max_length=256),
33+
),
34+
# Fix index naming: swap the names to match their conditions
35+
# history_decoded_processed_idx has processed=False (should be "not_proc")
36+
# history_decoded_not_proc_idx has processed=True (should be "processed")
37+
migrations.RenameIndex(
38+
model_name='internaltxdecoded',
39+
old_name='history_decoded_processed_idx',
40+
new_name='history_decoded_not_proc_idx_temp',
41+
),
42+
migrations.RenameIndex(
43+
model_name='internaltxdecoded',
44+
old_name='history_decoded_not_proc_idx',
45+
new_name='history_decoded_processed_idx',
46+
),
47+
migrations.RenameIndex(
48+
model_name='internaltxdecoded',
49+
old_name='history_decoded_not_proc_idx_temp',
50+
new_name='history_decoded_not_proc_idx',
51+
),
52+
]

safe_transaction_service/history/models.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,18 +428,18 @@ class EthereumTx(TimeStampedModel):
428428
tx_hash = Keccak256Field(primary_key=True)
429429
gas_used = Uint256Field(null=True, default=None) # If mined
430430
status = models.IntegerField(
431-
null=True, default=None, db_index=True
431+
null=True, default=None
432432
) # If mined. Old txs don't have `status`
433433
logs = ArrayField(JSONField(), null=True, default=None) # If mined
434434
transaction_index = models.PositiveIntegerField(null=True, default=None) # If mined
435-
_from = EthereumAddressBinaryField(null=True, db_index=True)
435+
_from = EthereumAddressBinaryField(null=True)
436436
gas = Uint256Field()
437437
gas_price = Uint256Field()
438438
max_fee_per_gas = Uint256Field(null=True, blank=True, default=None)
439439
max_priority_fee_per_gas = Uint256Field(null=True, blank=True, default=None)
440440
data = models.BinaryField(null=True)
441441
nonce = Uint256Field()
442-
to = EthereumAddressBinaryField(null=True, db_index=True)
442+
to = EthereumAddressBinaryField(null=True)
443443
value = Uint256Field()
444444
type = models.PositiveSmallIntegerField(default=0)
445445

@@ -1360,7 +1360,7 @@ class InternalTxDecoded(models.Model):
13601360
related_name="decoded_tx",
13611361
primary_key=True,
13621362
)
1363-
function_name = models.CharField(max_length=256, db_index=True)
1363+
function_name = models.CharField(max_length=256)
13641364
arguments = JSONField()
13651365
processed = models.BooleanField(default=False)
13661366
# Denormalized from internal_tx._from for efficient querying
@@ -1370,12 +1370,12 @@ class InternalTxDecoded(models.Model):
13701370
class Meta:
13711371
indexes = [
13721372
models.Index(
1373-
name="history_decoded_processed_idx",
1373+
name="history_decoded_not_proc_idx",
13741374
fields=["internal_tx_id"],
13751375
condition=Q(processed=False),
13761376
),
13771377
models.Index(
1378-
name="history_decoded_not_proc_idx",
1378+
name="history_decoded_processed_idx",
13791379
fields=["internal_tx_id"],
13801380
condition=Q(processed=True), # For finding out of order transactions
13811381
),

0 commit comments

Comments
 (0)