JobRunr 5.13 结合Postgres 12的查询高延迟问题求助
问题根源分析
爆发式任务生成后,jobrunr_jobs表积累了140多万条数据(从jobrunr_jobs_stats的total字段可确认),而jobrunr_jobs_stats的查询大概率是实时扫描全量任务数据计算统计值,导致这个带排序、分页的简单查询耗时极长,进而阻塞数据库。
解决方案
1. 紧急清理历史任务数据
手动清理已完成/标记为删除的任务,快速降低表数据量:
- 直接删除标记为
DELETED的任务:DELETE FROM jobrunr_jobs WHERE state = 'DELETED'; - 若需保留近期任务,按时间清理(示例保留7天内数据):
注意:数据量极大时,一次性删除可能锁表,可分批执行:DELETE FROM jobrunr_jobs WHERE finished_at < NOW() - INTERVAL '7 days';
重复执行直到清理完成。DELETE FROM jobrunr_jobs WHERE state = 'DELETED' LIMIT 1000;
2. 优化Jobrunr自动清理配置
Jobrunr自带任务清理机制,调整配置让它自动定期清理旧任务(Java配置示例):
JobRunr.configure() .usePostgresStorage(dataSource) .withJobScheduler() .withCleanupConfiguration(CleanupConfiguration.builder() .keepJobsFor(Duration.ofDays(3)) // 根据业务需求设置保留时长,无需过久 .cleanupInterval(Duration.ofHours(1)) // 每小时执行一次清理 .build()) .initialize();
3. 给任务表加索引加速统计查询
若暂时无法清理数据,给jobrunr_jobs表加索引,减少统计计算时的全表扫描:
CREATE INDEX idx_jobrunr_jobs_state_finished ON jobrunr_jobs(state, finished_at);
4. 改用物化视图替代实时统计
如果jobrunr_jobs_stats是视图而非物理表,可将其改为物化视图,定时刷新统计值,避免每次查询都实时计算:
-- 创建物化视图 CREATE MATERIALIZED VIEW jobrunr_jobs_stats_mv AS SELECT COUNT(*) AS total, SUM(CASE WHEN state = 'SCHEDULED' THEN 1 ELSE 0 END) AS scheduled, SUM(CASE WHEN state = 'ENQUEUED' THEN 1 ELSE 0 END) AS enqueued, SUM(CASE WHEN state = 'PROCESSING' THEN 1 ELSE 0 END) AS processing, SUM(CASE WHEN state = 'FAILED' THEN 1 ELSE 0 END) AS failed, SUM(CASE WHEN state = 'SUCCEEDED' THEN 1 ELSE 0 END) AS succeeded, SUM(CASE WHEN state = 'SUCCEEDED' THEN 1 ELSE 0 END) OVER() AS alltimesucceeded, SUM(CASE WHEN state = 'DELETED' THEN 1 ELSE 0 END) AS deleted, (SELECT COUNT(DISTINCT server_id) FROM jobrunr_background_job_servers) AS nbrofbackgroundjobservers, (SELECT COUNT(*) FROM jobrunr_recurring_jobs) AS nbrofrecurringjobs FROM jobrunr_jobs; -- 定时刷新(示例每小时刷新一次) REFRESH MATERIALIZED VIEW jobrunr_jobs_stats_mv;
之后应用内改为查询这个物化视图,可大幅降低查询延迟。
内容的提问来源于stack exchange,提问作者raptor379
相关产品推荐
相关产品推荐

