perf(db): add index on sbom_external_node(sbom_id, external_node_ref)#2404
perf(db): add index on sbom_external_node(sbom_id, external_node_ref)#2404mrrajan wants to merge 1 commit into
Conversation
Eliminates sequential scan during external node resolution. Verified: Seq Scan → Index Scan on hosted environment. Implements TC-4750 Assisted-by: Claude Code
Reviewer's GuideAdds a new SeaORM migration to create a composite index on sbom_external_node(sbom_id, external_node_ref) and wires it into the migrator so external node resolution can use an index scan instead of a sequential scan. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2404 +/- ##
==========================================
+ Coverage 71.37% 71.39% +0.01%
==========================================
Files 441 442 +1
Lines 26747 26896 +149
Branches 26747 26896 +149
==========================================
+ Hits 19092 19202 +110
- Misses 6541 6565 +24
- Partials 1114 1129 +15 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@mrrajan considering current and ongoing work on 0.4.z (which will push to main) I think this PR can be closed ... do you agree ? |
There was a problem hiding this comment.
This index impacts latest analysis endpoints with an example query being at collector.rs:271-276:
sbom_external_node::Entity::find()
.filter(sbom_external_node::Column::SbomId.eq(sbom_external_node.sbom_id))
.filter(sbom_external_node::Column::ExternalNodeRef.eq(&sbom_external_node.node_id))
.one(self.connection)
but testing (perf and sql) shows no appreciable difference between status quo and using new index:
before
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT *
FROM sbom_external_node
WHERE sbom_id = '019661ca-0df3-7413-a43d-c45aab8e9200'
AND external_node_ref = 'SPDXRef-A'
LIMIT 1;
+----------------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN |
|----------------------------------------------------------------------------------------------------------------------------------------------------|
| Limit (cost=0.42..4.69 rows=1 width=319) (actual time=0.014..0.014 rows=0 loops=1) |
| Buffers: shared hit=4 |
| -> Index Scan using sbom_external_node_pkey on sbom_external_node (cost=0.42..4.69 rows=1 width=319) (actual time=0.013..0.013 rows=0 loops=1) |
| Index Cond: (sbom_id = '019661ca-0df3-7413-a43d-c45aab8e9200'::uuid) |
| Filter: ((external_node_ref)::text = 'SPDXRef-A'::text) |
| Rows Removed by Filter: 10 |
| Buffers: shared hit=4 |
| Planning: |
| Buffers: shared hit=41 |
| Planning Time: 0.209 ms |
| Execution Time: 0.030 ms
after
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT *
FROM sbom_external_node
WHERE sbom_id = '019661ca-0df3-7413-a43d-c45aab8e9200'
AND external_node_ref = 'SPDXRef-A'
LIMIT 1;
+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| Limit (cost=0.42..2.64 rows=1 width=320) (actual time=0.014..0.015 rows=0 loops=1) |
| Buffers: shared hit=3 |
| -> Index Scan using tmp_idx_sbom_external_node_ref on sbom_external_node (cost=0.42..2.64 rows=1 width=320) (actual time=0.013..0.014 rows=0 loops=1) |
| Index Cond: ((sbom_id = '019661ca-0df3-7413-a43d-c45aab8e9200'::uuid) AND ((external_node_ref)::text = 'SPDXRef-A'::text)) |
| Buffers: shared hit=3 |
| Planning Time: 0.110 ms |
| Execution Time: 0.030 ms
shows where the new tmp_idx_sbom_external_node_ref is used but basically equiv execution time to existing.
This index would help if an SBOM has a large number of external nodes per sbom_id (hundreds or thousands), where the PK scan + filter would touch many pages which is never the case for rh sboms (usually just a 1 to 1 type relationship).
I think this PR can be closed.
Eliminates sequential scan during external node resolution. Verified: Seq Scan → Index Scan on hosted environment.
Implements TC-4750
Assisted-by: Claude Code
Summary by Sourcery
Enhancements: