From cc84443959facee2c483f2fbb623a8be825400ac Mon Sep 17 00:00:00 2001 From: Dan Crews Date: Tue, 18 Aug 2026 14:42:09 -0700 Subject: [PATCH] fix: add blueprint_id index to _devlake_pipelines GET /blueprints/:blueprintId/pipelines runs COUNT(*) and a filtered SELECT on _devlake_pipelines.blueprint_id, but the column was unindexed. On instances with tens of thousands of pipeline rows this forces a full table scan on every request; observed ~30s for a table of 34k rows, causing upstream request timeouts in config-ui. Add a gorm index tag on Pipeline.BlueprintId for fresh installs and a migration script to add the index to existing installs. Signed-off-by: Dan Crews --- ...818_add_blueprint_id_index_to_pipelines.go | 46 +++++++++++++++++++ .../core/models/migrationscripts/register.go | 1 + backend/core/models/pipeline.go | 2 +- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 backend/core/models/migrationscripts/20260818_add_blueprint_id_index_to_pipelines.go diff --git a/backend/core/models/migrationscripts/20260818_add_blueprint_id_index_to_pipelines.go b/backend/core/models/migrationscripts/20260818_add_blueprint_id_index_to_pipelines.go new file mode 100644 index 00000000000..8b541468a3c --- /dev/null +++ b/backend/core/models/migrationscripts/20260818_add_blueprint_id_index_to_pipelines.go @@ -0,0 +1,46 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package migrationscripts + +import ( + "github.com/apache/incubator-devlake/core/context" + "github.com/apache/incubator-devlake/core/errors" + "github.com/apache/incubator-devlake/helpers/migrationhelper" +) + +type addBlueprintIdIndexToPipelines struct{} + +type pipeline20260818 struct { + BlueprintId uint64 `gorm:"index"` +} + +func (pipeline20260818) TableName() string { + return "_devlake_pipelines" +} + +func (u *addBlueprintIdIndexToPipelines) Up(basicRes context.BasicRes) errors.Error { + return migrationhelper.AutoMigrateTables(basicRes, &pipeline20260818{}) +} + +func (*addBlueprintIdIndexToPipelines) Version() uint64 { + return 20260818000001 +} + +func (*addBlueprintIdIndexToPipelines) Name() string { + return "add blueprint_id index for _devlake_pipelines" +} diff --git a/backend/core/models/migrationscripts/register.go b/backend/core/models/migrationscripts/register.go index 69ab4d673de..22f5f9e6d53 100644 --- a/backend/core/models/migrationscripts/register.go +++ b/backend/core/models/migrationscripts/register.go @@ -150,5 +150,6 @@ func All() []plugin.MigrationScript { new(addCqProjectMetricsHistory), new(addIsBotToAccounts), new(addSprintVelocityFields), + new(addBlueprintIdIndexToPipelines), } } diff --git a/backend/core/models/pipeline.go b/backend/core/models/pipeline.go index f9613dd0e06..a3c0dcae7cb 100644 --- a/backend/core/models/pipeline.go +++ b/backend/core/models/pipeline.go @@ -54,7 +54,7 @@ func (plan PipelinePlan) IsEmpty() bool { type Pipeline struct { common.Model Name string `json:"name" gorm:"index"` - BlueprintId uint64 `json:"blueprintId"` + BlueprintId uint64 `json:"blueprintId" gorm:"index"` Plan PipelinePlan `json:"plan" gorm:"serializer:encdec"` TotalTasks int `json:"totalTasks"` FinishedTasks int `json:"finishedTasks"`