Range queries are not effective as the first argument, switching to kind, key, created_at index, which also almost invalidates the need for the Replaceable idx and is only kept for the unique key consistency

This commit is contained in:
Vitor Pamplona
2026-01-01 12:51:43 -05:00
parent 8affb2564b
commit aac880c575
3 changed files with 27 additions and 32 deletions
@@ -113,17 +113,16 @@ class ReplaceableTest {
@Test @Test
fun testTriggersIndexUsageKind0() { fun testTriggersIndexUsageKind0() {
val explainer = val sql =
db.store.explainQuery( """
""" SELECT * FROM event_headers
SELECT * FROM event_headers WHERE
WHERE event_headers.kind = 0 AND
event_headers.kind = 0 AND event_headers.pubkey = 'aa' AND
event_headers.pubkey = 'aa' AND event_headers.created_at < 1766686500
event_headers.created_at < 1766686500 AND """.trimIndent()
((event_headers.kind IN (0, 3)) OR (event_headers.kind >= 10000 AND event_headers.kind < 20000));
""".trimIndent(), val explainer = db.store.explainQuery(sql)
)
assertEquals( assertEquals(
""" """
@@ -131,9 +130,8 @@ class ReplaceableTest {
WHERE WHERE
event_headers.kind = 0 AND event_headers.kind = 0 AND
event_headers.pubkey = 'aa' AND event_headers.pubkey = 'aa' AND
event_headers.created_at < 1766686500 AND event_headers.created_at < 1766686500
((event_headers.kind IN (0, 3)) OR (event_headers.kind >= 10000 AND event_headers.kind < 20000)); └── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at<?)
└── SEARCH event_headers USING INDEX replaceable_idx (kind=? AND pubkey=?)
""".trimIndent(), """.trimIndent(),
explainer, explainer,
) )
@@ -141,17 +139,16 @@ class ReplaceableTest {
@Test @Test
fun testTriggersIndexUsageKind3() { fun testTriggersIndexUsageKind3() {
val explainer = val sql =
db.store.explainQuery( """
""" SELECT * FROM event_headers
SELECT * FROM event_headers WHERE
WHERE event_headers.kind = 3 AND
event_headers.kind = 3 AND event_headers.pubkey = 'aa' AND
event_headers.pubkey = 'aa' AND event_headers.created_at < 1766686500
event_headers.created_at < 1766686500 AND """.trimIndent()
((event_headers.kind IN (0, 3)) OR (event_headers.kind >= 10000 AND event_headers.kind < 20000));
""".trimIndent(), val explainer = db.store.explainQuery(sql)
)
assertEquals( assertEquals(
""" """
@@ -159,9 +156,8 @@ class ReplaceableTest {
WHERE WHERE
event_headers.kind = 3 AND event_headers.kind = 3 AND
event_headers.pubkey = 'aa' AND event_headers.pubkey = 'aa' AND
event_headers.created_at < 1766686500 AND event_headers.created_at < 1766686500
((event_headers.kind IN (0, 3)) OR (event_headers.kind >= 10000 AND event_headers.kind < 20000)); └── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at<?)
└── SEARCH event_headers USING INDEX replaceable_idx (kind=? AND pubkey=?)
""".trimIndent(), """.trimIndent(),
explainer, explainer,
) )
@@ -69,8 +69,8 @@ class EventIndexesModule(
// queries by limit (latest records), since, until (sync all) alone // queries by limit (latest records), since, until (sync all) alone
db.execSQL("CREATE INDEX query_by_created_at_id ON event_headers (created_at DESC, id)") db.execSQL("CREATE INDEX query_by_created_at_id ON event_headers (created_at DESC, id)")
// need to check if this is actually needed. // queries by kind + pubkey, but not d-tag, even if they are replaceables and addressables, by date.
db.execSQL("CREATE INDEX query_by_created_at_kind_key ON event_headers (created_at DESC, kind, pubkey)") db.execSQL("CREATE INDEX query_by_kind_pubkey_created ON event_headers (kind, pubkey, created_at DESC)")
// makes deletions on the event_header fast // makes deletions on the event_header fast
db.execSQL("CREATE INDEX fk_event_tags_header_id ON event_tags (event_header_row_id)") db.execSQL("CREATE INDEX fk_event_tags_header_id ON event_tags (event_header_row_id)")
@@ -48,8 +48,7 @@ class ReplaceableModule : IModule {
WHERE WHERE
event_headers.kind = NEW.kind AND event_headers.kind = NEW.kind AND
event_headers.pubkey = NEW.pubkey AND event_headers.pubkey = NEW.pubkey AND
event_headers.created_at < NEW.created_at AND event_headers.created_at < NEW.created_at;
((event_headers.kind IN (0, 3)) OR (event_headers.kind >= 10000 AND event_headers.kind < 20000));
END; END;
""".trimIndent(), """.trimIndent(),
) )