perf(actions): is_reusable_caller index makes SQLite read nearly every job row (#40055)

On SQLite, the `is_reusable_caller = false` filters (e.g. the admin job
queue page) are planned from `IDX_action_run_job_is_reusable_caller`,
which matches almost every row, so nearly the whole `action_run_job`
table is read. `ANALYZE` does not help: `sqlite_stat1` only keeps
average rows per key.

No query needs that index. `is_reusable_caller = true` is only used by
`expandedCallerCond`, always together with `repo_id` and
`concurrency_group`. Their plans use other indexes on SQLite, PostgreSQL
17 and MySQL 8.4 (PostgreSQL is slightly slower with it).

This removes the index tag. `SyncAllTables` drops the existing index on
the next start, so no migration is needed.

Job queue count on SQLite, before: a search on the `is_reusable_caller`
index; after: a `MULTI-INDEX OR` on the `status` and `pickup` indexes.
On an instance with about 7,000 jobs the admin job queue page went from
`Page: 784ms` to `39ms` (measured with an earlier revision of this PR
that gave the same plan).

---------

Signed-off-by: Myers Carpenter <myers@maski.org>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Myers Carpenterandwxiaoguang authored and GitHub committed 2026-10-28 19:25:58 +00:00
1 parent 1ebeade2c1
commit 965d7522e0
1 file changed
+1 -1
+1 -1
View File
@@ -99,7 +99,7 @@ type ActionRunJob struct {
// IsReusableCaller marks this job as a reusable workflow caller.
// Caller jobs do not run on a runner; their status is derived from their child jobs.
IsReusableCaller bool `xorm:"index NOT NULL DEFAULT FALSE"`
IsReusableCaller bool `xorm:"NOT NULL DEFAULT FALSE"`
// IsExpanded reports whether this job's lazy expansion (children-row insertion) is complete.
// For a reusable workflow caller, true means children rows exist and CallPayload is populated.
IsExpanded bool `xorm:"NOT NULL DEFAULT FALSE"`