Skip to content

Commit af898a0

Browse files
authored
refactor: De-complexify 'count' metric (#97)
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.
1 parent d84ad27 commit af898a0

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
@@ -119,11 +119,7 @@ def as_expression(aggregate_function, aggregate_expression, column_name)
119119
end
120120

121121
def count_grouped
122-
if Job.connection.supports_partial_index?
123-
failed_count_grouped.merge(live_count_grouped) { |_, l, f| l + f }
124-
else
125-
grouped_query(jobs, count: [:count, '*']).transform_values(&:count)
126-
end
122+
failed_count_grouped.merge(live_count_grouped) { |_, l, f| l + f }
127123
end
128124

129125
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
@@ -433,6 +433,7 @@ SELECT SUM(count) AS count,
433433
queue AS queue
434434
FROM (SELECT `delayed_jobs`.`priority`, `delayed_jobs`.`queue`, COUNT(*) AS count
435435
FROM `delayed_jobs`
436+
WHERE `delayed_jobs`.`failed_at` IS NOT NULL
436437
GROUP BY `delayed_jobs`.`priority`, `delayed_jobs`.`queue`) subquery
437438
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`
438439

@@ -442,10 +443,9 @@ SELECT SUM(count) AS count,
442443
-> Materialize (cost=...)
443444
-> Table scan on <temporary>
444445
-> Aggregate using temporary table
445-
-> Covering index scan on delayed_jobs using idx_delayed_jobs_live (cost=...)
446+
-> Filter: (delayed_jobs.failed_at is not null) (cost=...)
447+
-> Covering index range scan on delayed_jobs using idx_delayed_jobs_live over (NULL < failed_at) (cost=...)
446448
---
447-
-- QUERIES FOR `future_count`:
448-
---------------------------------
449449
SELECT SUM(count) AS count,
450450
SUM(future_count) AS future_count,
451451
SUM(erroring_count) AS erroring_count,
@@ -471,6 +471,9 @@ SELECT SUM(count) AS count,
471471
-> Filter: (delayed_jobs.failed_at is null) (cost=...)
472472
-> Covering index lookup on delayed_jobs using idx_delayed_jobs_live (failed_at = NULL) (cost=...)
473473
---
474+
-- QUERIES FOR `future_count`:
475+
---------------------------------
476+
-- (no new queries)
474477
-- QUERIES FOR `locked_count`:
475478
---------------------------------
476479
SELECT SUM(claimed_count) AS claimed_count,
@@ -503,24 +506,7 @@ SELECT SUM(claimed_count) AS claimed_count,
503506
-- (no new queries)
504507
-- QUERIES FOR `failed_count`:
505508
---------------------------------
506-
SELECT SUM(count) AS count,
507-
CASE WHEN priority < 10 THEN 0 WHEN priority < 20 THEN 10 WHEN priority < 30 THEN 20 WHEN priority >= 30 THEN 30 END AS priority,
508-
queue AS queue
509-
FROM (SELECT `delayed_jobs`.`priority`, `delayed_jobs`.`queue`, COUNT(*) AS count
510-
FROM `delayed_jobs`
511-
WHERE `delayed_jobs`.`failed_at` IS NOT NULL
512-
GROUP BY `delayed_jobs`.`priority`, `delayed_jobs`.`queue`) subquery
513-
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`
514-
515-
-> Table scan on <temporary>
516-
-> Aggregate using temporary table
517-
-> Table scan on subquery (cost=...)
518-
-> Materialize (cost=...)
519-
-> Table scan on <temporary>
520-
-> Aggregate using temporary table
521-
-> Filter: (delayed_jobs.failed_at is not null) (cost=...)
522-
-> Covering index range scan on delayed_jobs using idx_delayed_jobs_live over (NULL < failed_at) (cost=...)
523-
---
509+
-- (no new queries)
524510
-- QUERIES FOR `max_lock_age`:
525511
---------------------------------
526512
-- (no new queries)
@@ -546,6 +532,7 @@ SELECT SUM(count) AS count,
546532
queue AS queue
547533
FROM (SELECT `delayed_jobs`.`priority`, `delayed_jobs`.`queue`, COUNT(*) AS count
548534
FROM `delayed_jobs`
535+
WHERE `delayed_jobs`.`failed_at` IS NOT NULL
549536
GROUP BY `delayed_jobs`.`priority`, `delayed_jobs`.`queue`) subquery
550537
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`
551538

@@ -555,10 +542,9 @@ SELECT SUM(count) AS count,
555542
-> Materialize (cost=...)
556543
-> Table scan on <temporary>
557544
-> Aggregate using temporary table
558-
-> Table scan on delayed_jobs (cost=...)
545+
-> Filter: (delayed_jobs.failed_at is not null) (cost=...)
546+
-> Table scan on delayed_jobs (cost=...)
559547
---
560-
-- QUERIES FOR `future_count`:
561-
---------------------------------
562548
SELECT SUM(count) AS count,
563549
SUM(future_count) AS future_count,
564550
SUM(erroring_count) AS erroring_count,
@@ -584,6 +570,9 @@ SELECT SUM(count) AS count,
584570
-> Filter: (delayed_jobs.failed_at is null) (cost=...)
585571
-> Table scan on delayed_jobs (cost=...)
586572
---
573+
-- QUERIES FOR `future_count`:
574+
---------------------------------
575+
-- (no new queries)
587576
-- QUERIES FOR `locked_count`:
588577
---------------------------------
589578
SELECT SUM(claimed_count) AS claimed_count,
@@ -616,24 +605,7 @@ SELECT SUM(claimed_count) AS claimed_count,
616605
-- (no new queries)
617606
-- QUERIES FOR `failed_count`:
618607
---------------------------------
619-
SELECT SUM(count) AS count,
620-
CASE WHEN priority < 10 THEN 0 WHEN priority < 20 THEN 10 WHEN priority < 30 THEN 20 WHEN priority >= 30 THEN 30 END AS priority,
621-
queue AS queue
622-
FROM (SELECT `delayed_jobs`.`priority`, `delayed_jobs`.`queue`, COUNT(*) AS count
623-
FROM `delayed_jobs`
624-
WHERE `delayed_jobs`.`failed_at` IS NOT NULL
625-
GROUP BY `delayed_jobs`.`priority`, `delayed_jobs`.`queue`) subquery
626-
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`
627-
628-
-> Table scan on <temporary>
629-
-> Aggregate using temporary table
630-
-> Table scan on subquery (cost=...)
631-
-> Materialize (cost=...)
632-
-> Table scan on <temporary>
633-
-> Aggregate using temporary table
634-
-> Filter: (delayed_jobs.failed_at is not null) (cost=...)
635-
-> Table scan on delayed_jobs (cost=...)
636-
---
608+
-- (no new queries)
637609
-- QUERIES FOR `max_lock_age`:
638610
---------------------------------
639611
-- (no new queries)

0 commit comments

Comments
 (0)