1. 问题现象与背景分析
最近在排查DolphinScheduler生产环境性能问题时,发现工作流实例列表页面加载异常缓慢,每次打开都需要转圈10秒以上才能显示数据。作为核心调度系统,这种延迟已经严重影响了日常运维效率。
通过Chrome开发者工具抓包分析,发现主要耗时集中在接口/dolphinscheduler/projects/{projectCode}/process/instances的响应时间上。该接口需要返回项目下的工作流实例列表,包含实例状态、起止时间等关键信息。
2. 数据库层面问题定位
2.1 慢查询日志分析
在MySQL慢查询日志中发现了如下典型慢SQL(表名已脱敏):
SELECT * FROM t_ds_process_instance WHERE project_code = 123456 ORDER BY start_time DESC LIMIT 0, 10;这个看似简单的查询执行时间竟达到8.2秒,说明存在严重的索引缺失问题。
2.2 表结构检查
检查t_ds_process_instance表结构发现:
- 数据量:约120万条记录
- 现有索引:仅有主键id的聚簇索引
- 查询条件:project_code字段无索引
- 排序字段:start_time字段无索引
3. 索引优化方案设计
3.1 复合索引选择
针对这个查询场景,最有效的方案是创建(project_code, start_time)的复合索引:
ALTER TABLE t_ds_process_instance ADD INDEX idx_project_start_time (project_code, start_time);选择这个组合是因为:
- project_code是等值查询条件,应该作为联合索引的第一列
- start_time用于排序,放在第二列可以利用索引的有序性
- 覆盖了WHERE和ORDER BY两个关键操作
3.2 索引设计原理
这个复合索引的工作方式:
- B+树首先按project_code有序存储
- 相同project_code下按start_time倒序排列
- 查询时可以直接定位到指定project_code的数据块
- 由于索引本身有序,不需要额外的排序操作
- 使用LIMIT只需要扫描少量记录即可返回
4. 优化效果验证
4.1 执行计划对比
优化前:
type: ALL rows: 1200000 Extra: Using filesort优化后:
type: ref rows: 500 Extra: Using index4.2 性能指标
| 指标 | 优化前 | 优化后 | 提升幅度 |
|---|---|---|---|
| 查询耗时 | 8200ms | 23ms | 356倍 |
| CPU消耗 | 85% | 2% | 97%下降 |
| 接口响应时间 | 10s+ | 300ms | 33倍 |
5. 深入优化建议
5.1 索引使用注意事项
虽然这个索引解决了当前问题,但需要注意:
- 索引会增加约5%的存储空间
- 写操作需要维护索引,会略微降低插入速度
- 不同项目间的查询可能需要不同的索引策略
5.2 其他潜在优化点
- 历史数据归档:将3个月前的完成实例移到历史表
- 查询缓存:对高频访问的项目启用结果缓存
- 分页优化:避免深度分页(如LIMIT 10000,10)
6. 生产环境实施记录
实际实施步骤:
- 在测试环境验证索引效果
- 选择业务低峰期执行ALTER TABLE
- 使用pt-online-schema-change工具避免锁表
- 执行后立即进行查询验证
重要提示:大表添加索引建议使用online DDL工具,避免长时间锁表影响生产业务
7. 同类问题排查方法
对于类似的列表页性能问题,可以按照这个流程排查:
- 抓取前端接口请求,确认慢接口
- 分析后端SQL查询,识别慢查询
- 检查表结构和现有索引
- 设计针对性索引方案
- 测试验证后灰度上线
8. DolphinScheduler特定优化
针对DolphinScheduler的其他性能优化经验:
- 工作流定义表也需要类似的project_code索引
- 任务实例表建议添加process_instance_id索引
- 对于超大规模部署,考虑分库分表策略
- 定期执行ANALYZE TABLE更新统计信息
经过这次优化,不仅解决了当前列表页加载慢的问题,更为后续的性能优化建立了标准流程。索引虽小,却是数据库性能优化的第一道防线。