Skip to content

Commit d2a7765

Browse files
committed
refactor: De-complexify 'count' metric
Given that `live_count_grouped` is already necessary for computing all the other live queue metrics, we can reduce the work on MySQL by running `failed_count_grouped` (and filtering the scan down to fewer rows) instead of an entire count against the table. stack-info: PR: #97, branch: smudge/stack/8
1 parent 7561419 commit d2a7765

2 files changed

Lines changed: 15 additions & 47 deletions

File tree

lib/delayed/monitor.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,7 @@ def grouped_count(scope, include_db_time: false, **kwargs)
112112
end
113113

114114
def count_grouped
115-
if Job.connection.supports_partial_index?
116-
failed_count_grouped.merge(live_count_grouped) { |_, l, f| l + f }
117-
else
118-
grouped_count(jobs).transform_values(&:count)
119-
end
115+
failed_count_grouped.merge(live_count_grouped) { |_, l, f| l + f }
120116
end
121117

122118
def live_count_grouped

spec/delayed/__snapshots__/monitor_spec.rb.snap

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ SELECT SUM(count) AS count,
441441
queue AS queue
442442
FROM (SELECT `delayed_jobs`.`priority`, `delayed_jobs`.`queue`, COUNT(*) AS count
443443
FROM `delayed_jobs`
444+
WHERE `delayed_jobs`.`failed_at` IS NOT NULL
444445
GROUP BY `delayed_jobs`.`priority`, `delayed_jobs`.`queue`) subquery
445446
GROUP BY CASE WHEN priority < 10 THEN 0 WHEN priority < 20 THEN 10 WHEN priority < 30 THEN 20 WHEN priority >= 30 THEN 30 END, `queue`
446447

@@ -450,10 +451,9 @@ SELECT SUM(count) AS count,
450451
-> Materialize (cost=...)
451452
-> Table scan on <temporary>
452453
-> Aggregate using temporary table
453-
-> Covering index scan on delayed_jobs using idx_delayed_jobs_live (cost=...)
454+
-> Filter: (delayed_jobs.failed_at is not null) (cost=...)
455+
-> Covering index range scan on delayed_jobs using idx_delayed_jobs_live over (NULL < failed_at) (cost=...)
454456
---
455-
-- QUERIES FOR `future_count`:
456-
---------------------------------
457457
SELECT SUM(future_count) AS future_count,
458458
SUM(erroring_count) AS erroring_count,
459459
MIN(run_at) AS run_at,
@@ -479,6 +479,9 @@ SELECT SUM(future_count) AS future_count,
479479
-> Filter: (delayed_jobs.failed_at is null) (cost=...)
480480
-> Covering index lookup on delayed_jobs using idx_delayed_jobs_live (failed_at = NULL) (cost=...)
481481
---
482+
-- QUERIES FOR `future_count`:
483+
---------------------------------
484+
-- (no new queries)
482485
-- QUERIES FOR `locked_count`:
483486
---------------------------------
484487
SELECT SUM(claimed_count) AS claimed_count,
@@ -513,24 +516,7 @@ SELECT SUM(claimed_count) AS claimed_count,
513516
-- (no new queries)
514517
-- QUERIES FOR `failed_count`:
515518
---------------------------------
516-
SELECT SUM(count) AS count,
517-
CASE WHEN priority < 10 THEN 0 WHEN priority < 20 THEN 10 WHEN priority < 30 THEN 20 WHEN priority >= 30 THEN 30 END AS priority,
518-
queue AS queue
519-
FROM (SELECT `delayed_jobs`.`priority`, `delayed_jobs`.`queue`, COUNT(*) AS count
520-
FROM `delayed_jobs`
521-
WHERE `delayed_jobs`.`failed_at` IS NOT NULL
522-
GROUP BY `delayed_jobs`.`priority`, `delayed_jobs`.`queue`) subquery
523-
GROUP BY CASE WHEN priority < 10 THEN 0 WHEN priority < 20 THEN 10 WHEN priority < 30 THEN 20 WHEN priority >= 30 THEN 30 END, `queue`
524-
525-
-> Table scan on <temporary>
526-
-> Aggregate using temporary table
527-
-> Table scan on subquery (cost=...)
528-
-> Materialize (cost=...)
529-
-> Table scan on <temporary>
530-
-> Aggregate using temporary table
531-
-> Filter: (delayed_jobs.failed_at is not null) (cost=...)
532-
-> Covering index range scan on delayed_jobs using idx_delayed_jobs_live over (NULL < failed_at) (cost=...)
533-
---
519+
-- (no new queries)
534520
-- QUERIES FOR `max_lock_age`:
535521
---------------------------------
536522
-- (no new queries)
@@ -556,6 +542,7 @@ SELECT SUM(count) AS count,
556542
queue AS queue
557543
FROM (SELECT `delayed_jobs`.`priority`, `delayed_jobs`.`queue`, COUNT(*) AS count
558544
FROM `delayed_jobs`
545+
WHERE `delayed_jobs`.`failed_at` IS NOT NULL
559546
GROUP BY `delayed_jobs`.`priority`, `delayed_jobs`.`queue`) subquery
560547
GROUP BY CASE WHEN priority < 10 THEN 0 WHEN priority < 20 THEN 10 WHEN priority < 30 THEN 20 WHEN priority >= 30 THEN 30 END, `queue`
561548

@@ -565,10 +552,9 @@ SELECT SUM(count) AS count,
565552
-> Materialize (cost=...)
566553
-> Table scan on <temporary>
567554
-> Aggregate using temporary table
568-
-> Table scan on delayed_jobs (cost=...)
555+
-> Filter: (delayed_jobs.failed_at is not null) (cost=...)
556+
-> Table scan on delayed_jobs (cost=...)
569557
---
570-
-- QUERIES FOR `future_count`:
571-
---------------------------------
572558
SELECT SUM(future_count) AS future_count,
573559
SUM(erroring_count) AS erroring_count,
574560
MIN(run_at) AS run_at,
@@ -594,6 +580,9 @@ SELECT SUM(future_count) AS future_count,
594580
-> Filter: (delayed_jobs.failed_at is null) (cost=...)
595581
-> Table scan on delayed_jobs (cost=...)
596582
---
583+
-- QUERIES FOR `future_count`:
584+
---------------------------------
585+
-- (no new queries)
597586
-- QUERIES FOR `locked_count`:
598587
---------------------------------
599588
SELECT SUM(claimed_count) AS claimed_count,
@@ -628,24 +617,7 @@ SELECT SUM(claimed_count) AS claimed_count,
628617
-- (no new queries)
629618
-- QUERIES FOR `failed_count`:
630619
---------------------------------
631-
SELECT SUM(count) AS count,
632-
CASE WHEN priority < 10 THEN 0 WHEN priority < 20 THEN 10 WHEN priority < 30 THEN 20 WHEN priority >= 30 THEN 30 END AS priority,
633-
queue AS queue
634-
FROM (SELECT `delayed_jobs`.`priority`, `delayed_jobs`.`queue`, COUNT(*) AS count
635-
FROM `delayed_jobs`
636-
WHERE `delayed_jobs`.`failed_at` IS NOT NULL
637-
GROUP BY `delayed_jobs`.`priority`, `delayed_jobs`.`queue`) subquery
638-
GROUP BY CASE WHEN priority < 10 THEN 0 WHEN priority < 20 THEN 10 WHEN priority < 30 THEN 20 WHEN priority >= 30 THEN 30 END, `queue`
639-
640-
-> Table scan on <temporary>
641-
-> Aggregate using temporary table
642-
-> Table scan on subquery (cost=...)
643-
-> Materialize (cost=...)
644-
-> Table scan on <temporary>
645-
-> Aggregate using temporary table
646-
-> Filter: (delayed_jobs.failed_at is not null) (cost=...)
647-
-> Table scan on delayed_jobs (cost=...)
648-
---
620+
-- (no new queries)
649621
-- QUERIES FOR `max_lock_age`:
650622
---------------------------------
651623
-- (no new queries)

0 commit comments

Comments
 (0)