From 2619e24462354316b0643d71f155ef975a37678b Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Fri, 19 Jul 2024 10:53:44 +1000 Subject: [PATCH] fixup! fix: events: address sqlite index selection performance regressions --- chain/events/filter/index.go | 5 +++-- chain/events/filter/index_migrations.go | 23 ++++++++++++----------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/chain/events/filter/index.go b/chain/events/filter/index.go index 9112039f0dd..bec3888b16c 100644 --- a/chain/events/filter/index.go +++ b/chain/events/filter/index.go @@ -97,11 +97,12 @@ const ( // an index that narrows down results to an epoch or a reasonable range of epochs. Specifically, // event_tipset_key_cid or event_height should be the first index. Then further narrowing can take // place within the small subset of results. - // Unfortunately SQLite has some quicks in index selection that mean that certain query types will + // Unfortunately SQLite has some quirks in index selection that mean that certain query types will // bypass these indexes if alternatives are available. This has been observed specifically on // queries with height ranges: `height>=X AND height<=Y`. // - // e.g.: + // e.g. we want to see that `event_height` is the first index used in this query: + // // EXPLAIN QUERY PLAN // SELECT // event.height, event.tipset_key_cid, event_entry.indexed, event_entry.codec, event_entry.key, event_entry.value diff --git a/chain/events/filter/index_migrations.go b/chain/events/filter/index_migrations.go index e20675860ed..bf8fd2f943c 100644 --- a/chain/events/filter/index_migrations.go +++ b/chain/events/filter/index_migrations.go @@ -135,10 +135,11 @@ func migrationVersion2(db *sql.DB, chainStore *store.ChainStore) sqlite.Migratio } } -// migrationVersion3 migrates the schema from version 2 to version 3. It originally added two -// indices: 1) an index on the event.emitter_addr column, and 2) an index on the event_entry.key -// column. However, as of version 7, these indices have been removed as they were found to be a -// performance hindrance. This migration is now a no-op. +// migrationVersion3 migrates the schema from version 2 to version 3 by creating two indices: +// 1) an index on the event.emitter_addr column, and 2) an index on the event_entry.key column. +// +// As of version 7, these indices have been removed as they were found to be a performance +// hindrance. This migration is now a no-op. func migrationVersion3(ctx context.Context, tx *sql.Tx) error { return nil } @@ -154,8 +155,8 @@ func migrationVersion3(ctx context.Context, tx *sql.Tx) error { // 1. an index on the event.tipset_key_cid column // 2. an index on the event.height column // 3. an index on the event.reverted column (removed in version 7) -// 4. an index on the event_entry.indexed and event_entry.key columns (removed in version 7) -// 5. an index on the event_entry.codec and event_entry.value columns (removed in version 7) +// 4. a composite index on the event_entry.indexed and event_entry.key columns (removed in version 7) +// 5. a composite index on the event_entry.codec and event_entry.value columns (removed in version 7) // 6. an index on the event_entry.event_id column // // Indexes 3, 4, and 5 were removed in version 7 as they were found to be a performance hindrance so @@ -233,15 +234,15 @@ func migrationVersion6(ctx context.Context, tx *sql.Tx) error { // indices: // 1. the index on the event.emitter_addr column // 2. the index on the event.reverted column -// 3. the index on the event_entry.indexed and event_entry.key columns -// 4. the index on the event_entry.codec and event_entry.value columns +// 3. the composite index on the event_entry.indexed and event_entry.key columns +// 4. the composite index on the event_entry.codec and event_entry.value columns // // These indices were found to be a performance hindrance as they prevent SQLite from using the // intended initial indexes on height or tipset_key_cid in many query variations. Without additional // indices to fall-back on, SQLite is forced to narrow down each query via height or tipset_key_cid // which is the desired behavior. func migrationVersion7(ctx context.Context, tx *sql.Tx) error { - for _, create := range []struct { + for _, drop := range []struct { desc string query string }{ @@ -250,8 +251,8 @@ func migrationVersion7(ctx context.Context, tx *sql.Tx) error { {"drop index event_entry_indexed_key", "DROP INDEX IF EXISTS event_entry_indexed_key;"}, {"drop index event_entry_codec_value", "DROP INDEX IF EXISTS event_entry_codec_value;"}, } { - if _, err := tx.ExecContext(ctx, create.query); err != nil { - return xerrors.Errorf("%s: %w", create.desc, err) + if _, err := tx.ExecContext(ctx, drop.query); err != nil { + return xerrors.Errorf("%s: %w", drop.desc, err) } }