Activiti工作流引擎,关于百万级单表分页查询的一些优化实践

针对Activiti工作流引擎在SaaS环境下多租户、多用户场景中出现的单表百万级数据查询问题,本文详细介绍了如何优化复杂关联查询的SQL语句,通过减少不必要的字段查询和利用PageHelper的手写count支持,将查询时间从138秒降低至可接受范围,有效提升系统性能。

在Activiti工作流引擎项目Saas改造中,会遇到说多租户多用户的情况,那么每个表单数据量也会变多,单表百万级需求就成为一个必须要解决的问题。
别说可以用分库分表的方案,分库分表已经解决了千万级大表数据的情况了,总不能总是依赖数据库中间件分库分表方案,因为该方案分片是需要预先设定好的,如果改动分片策略或者分片数量,需要重新导数据,十分麻烦。那么使单表能够支持多一些数据的查询就尤为重要,尤其是流程引擎项目中设计到很多的关联查询,如下:
sql=

select F0000001,CreatedTime,a.act_result as actResult, (select user_name from sys_user su WHERE su.id=a.start_user_Id) As startUserId, a.start_user_name as startUserName, (SELECT GROUP_CONCAT(distinct user_name) from sys_user su LEFT JOIN ru_wf_task rwt ON su.id = rwt.deal_id WHERE rwt.app_run_id=a.id and rwt.status='1') as assignee, (select GROUP_CONCAT(distinct deal_name) from ru_wf_task rwt where rwt.app_run_id = a.id and rwt.status = '1') as assigneeName, a.id as appRunId,a.instance_id as instanceId,a.name_schema as Name,a.id as ObjectId, a.start_time as startTime from t_6e676bef4b68ddceb826429b8db311f1 t left join ru_wf_apprun a on a.id = t.app_run_id where a.app_id = 'b4cffb1a1a234d2eb673c2b33c30a7e8462383049' and t.company_id = '1'  order by create_time desc

十分蛋疼,在百万级单库t_6e676bef4b68ddceb826429b8db311f1里面要跑138s,前端早就卡死了噢,但是这个分页需求,使用mybatis的pagehelper后面还要在sql后面加上Limit 0,10。
分页sql

select F0000001,CreatedTime,a.act_result as actResult, (select user_name from sys_user su WHERE su.id=a.start_user_Id) As startUserId, a.start_user_name as startUserName, (SELECT GROUP_CONCAT(distinct user_name) from sys_user su LEFT JOIN ru_wf_task rwt ON su.id = rwt.deal_id WHERE rwt.app_run_id=a.id and rwt.status='1') as assignee, (select GROUP_CONCAT(distinct deal_name) from ru_wf_task rwt where rwt.app_run_id = a.id and rwt.status = '1') as assigneeName, a.id as appRunId,a.instance_id as instanceId,a.name_schema as Name,a.id as ObjectId, a.start_time as startTime from t_6e676bef4b68ddceb826429b8db311f1 t left join ru_wf_apprun a on a.id = t.app_run_id where a.app_id = 'b4cffb1a1a234d2eb673c2b33c30a7e8462383049' and t.company_id = '1'  order by create_time desc limit 010

单独执行这个语句,大概1.8s其实还算能接受了,相比原来,但是pagehelper插件需要做一个select count(0) from (" + sql + ")as total的操作,这个操作会遍历全表,那就非常慢了,关键是sql就要138s了,再count怎么行。其实分析这个语句的目的就能发现,count最后只是返回一个数字而已,那么sql是不是可以优化一下使count更快一点呢?可以参考
https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/Changelog.md
5.0.4版本已经添加了手写count支持。

然后我把sql优化一下,去掉不必要的查询,count语句为

select count(0) from (select 0 from t_6e676bef4b68ddceb826429b8db311f1 t left join ru_wf_apprun a on a.id = t.app_run_id where a.app_id = 'b4cffb1a1a234d2eb673c2b33c30a7e8462383049' and t.company_id = '1' )as total;

运行耗时5.9s,已经可以勉强接受了,配合分库分表方案,可以支撑Saas环境下的大数据量了。后面想到还有哪些优化再写吧。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值