统计查询慢一般怎么处理

医手 2020-06-09 11:52:15
每天都会有任务产生,每个任务都有对应的执行人。
然后要统计出:未完成的任务数,未完成任务的人数。并且是按任务创建日期到现在的天数来汇总的,例如1-3天内的数量,3-10天内的数量, 10天以上的数量。

60多万条未完成的任务,统计一下要6秒多。

感觉这个直接放在redis,每次加1减1都不太好使。因为涉及到人数.。当一个人完成一个任务,任务数自然是要减1,但人数却不一定。因为你也不知道他3-10天内的所有任务是不是都完成了。
...全文
8770 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_37721161 2021-03-04
  • 打赏
  • 举报
回复
用kettle把查询结果插入到一张表里,程序直接查那张表就行了
di_yun_hah 2020-07-16
  • 打赏
  • 举报
回复
这个要结合业务来看,如果之前的数据基本上不会发生改变的话,可以用业务表封装数据去跑定时任务,如果要求实时再做增量即可,如果之前的数据会发生改变,可以考虑用一些消息中间件去实现更改的逻辑,这样针对用户的交互要好很多,数据量上去了的话,还可以考虑把信息做横向切分,这些都是方法,不能单单在数据库上钻牛角尖
evanweng 2020-07-15
  • 打赏
  • 举报
回复
给我个表,可以帮你优化一下sql
nayi_224 2020-07-14
  • 打赏
  • 举报
回复
引用 5 楼 医手 的回复:
SELECT 1 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 1 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 0 DAY)
UNION ALL
SELECT 2 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 2 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 1 DAY)
UNION ALL
SELECT 3 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 3 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 2 DAY)
UNION ALL
SELECT 4 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 10 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 3 DAY)
UNION ALL
SELECT 10 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt<DATE_SUB(DATE(NOW()),INTERVAL 10 DAY)
执行语句是这样的。表是有按WHERE来建索引的KEY `Task_Ix_Main` (`CompanyId`,`State`,`CreatedAt`) 想从语句和索引上来优化,我觉得已经没可能了。
问题就是出在这个语句上,就这么写肯定慢。 这个语句主要慢在对一个60w的表搜索了5次。至于索引,你可以试着换一下位置试试,有可能索引效率也有问题,这个跟数据特征有关。 解决方法 1。从sql上改,使用rollup或者动态构造时间临时表做关联,都可以让task表的搜索次数降为1 2。从结构上改,做历史数据沉淀,每天跑一个定时任务,把10天前的数据做统计之后存到历史表里
Zzzz_zzzz_zz 2020-07-14
  • 打赏
  • 举报
回复
这个是看你自己的需求进行处理,可以定时任务固化,可以多线程处理,oracle还有物化视图。sql的优化就不说了。可以根据情况考虑表分区。
戎码一生灬 2020-07-14
  • 打赏
  • 举报
回复
我之前做的mysql单表两亿多数据的统计分析,耗时五分钟,后来果断改为impala查询了
fancy橙子 2020-06-23
  • 打赏
  • 举报
回复
6楼正解
vswen5 2020-06-23
  • 打赏
  • 举报
回复
新建个表 开个定时任务 每天去统计
evanweng 2020-06-22
  • 打赏
  • 举报
回复
感觉这个sql可以优化,把所有数据查询出来,然后在select后面做文章,用什么case,if,ifnull,或者左连右连。
程序员小杨* 2020-06-20
  • 打赏
  • 举报
回复
先查SQL语句,查完之后再利用多线程跑,整个过程上加入缓存,执行效率很高
冰思雨 2020-06-19
  • 打赏
  • 举报
回复
UserId 和 DepartId 在 DISTINCT 的时候,可能会用到索引,如果楼主有测试机的话,可以在复合索引中,添加这两项试试,看看能否会用的到。 KEY `Task_Ix_Main` (`CompanyId`,`State`,`CreatedAt`,`UserId`,`DepartId`) 或者换个思路,搞复杂一些。 像楼主这种事情,属于每天一次统计,就可以了,之后再统计,结果都不会发生变化。 既然如此,那不如做一个后台定时任务,每天零点一过,就开始进行一次统计,把统计结果,建张表存进去。 这样的话,之后的查询,直接从结果表中找到今天凌晨执行的结果,显示出来就OK了。 当然了,把统计结果保存到Redis里面也可以。不是每个Task的记录,是统计之后的结果。 如果统计结果中存在,每次查询都有变化的部分,那么,可以把其余的部分保存起来,变化的部分进行统计,然后,合并之后显示给用户。
薯条大爹 2020-06-12
  • 打赏
  • 举报
回复
1、sql语句进行优化 加索引 2、新建临时表进行同步查询 3、提前把自己想要的数据查询到后放进缓存 4、跑多线程进行查询也可以 方案很多,主要用最方便最简单的方案实现 才是正确
锦秀北里 2020-06-11
  • 打赏
  • 举报
回复
要么在sql上优化,要么就是一下子都查出来,之后在代码里去写统计计算逻辑
sun0322 2020-06-11
  • 打赏
  • 举报
回复
引用 6 楼 冬雪晶 的回复:
[quote=引用 5 楼 医手 的回复:]
SELECT 1 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 1 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 0 DAY)
UNION ALL
SELECT 2 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 2 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 1 DAY)
UNION ALL
SELECT 3 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 3 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 2 DAY)
UNION ALL
SELECT 4 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 10 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 3 DAY)
UNION ALL
SELECT 10 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt<DATE_SUB(DATE(NOW()),INTERVAL 10 DAY)
执行语句是这样的。表是有按WHERE来建索引的KEY `Task_Ix_Main` (`CompanyId`,`State`,`CreatedAt`) 想从语句和索引上来优化,我觉得已经没可能了。
sql拆开,跑多线程啊; 我最近也在做统计分析,每个接口耗时100毫秒左右[/quote] +1
s478853630 2020-06-09
  • 打赏
  • 举报
回复
引用 5 楼 医手 的回复:
SELECT 1 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 1 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 0 DAY)
UNION ALL
SELECT 2 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 2 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 1 DAY)
UNION ALL
SELECT 3 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 3 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 2 DAY)
UNION ALL
SELECT 4 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 10 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 3 DAY)
UNION ALL
SELECT 10 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt<DATE_SUB(DATE(NOW()),INTERVAL 10 DAY)
执行语句是这样的。表是有按WHERE来建索引的KEY `Task_Ix_Main` (`CompanyId`,`State`,`CreatedAt`) 想从语句和索引上来优化,我觉得已经没可能了。
sql拆开,跑多线程啊; 我最近也在做统计分析,每个接口耗时100毫秒左右
医手 2020-06-09
  • 打赏
  • 举报
回复
SELECT 1 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 1 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 0 DAY)
UNION ALL
SELECT 2 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 2 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 1 DAY)
UNION ALL
SELECT 3 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 3 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 2 DAY)
UNION ALL
SELECT 4 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt BETWEEN DATE_SUB(DATE(NOW()),INTERVAL 10 DAY) AND DATE_SUB(DATE(NOW()),INTERVAL 3 DAY)
UNION ALL
SELECT 10 天数, COUNT(1) 任务 ,COUNT(DISTINCT UserId) 人员,COUNT(DISTINCT DepartId) 部门
FROM Task
WHERE CompanyId ='18699d7c-aa26-11ea-b164-00163e069cdf'
      AND  State = 0
      AND CreatedAt<DATE_SUB(DATE(NOW()),INTERVAL 10 DAY)
执行语句是这样的。表是有按WHERE来建索引的KEY `Task_Ix_Main` (`CompanyId`,`State`,`CreatedAt`) 想从语句和索引上来优化,我觉得已经没可能了。
一只三黄鸡 2020-06-09
  • 打赏
  • 举报
回复
具体情况具体分析 用视图?
亦夜 2020-06-09
  • 打赏
  • 举报
回复
6秒这个确实太慢了,首先看程序代码是不是有逻辑不合理的地方,其次看一下是不是数据库的原因,然后使用执行计划看一下sql等级是否过低
dkwuxiang 2020-06-09
  • 打赏
  • 举报
回复
sql 语句怎么写的
tianfang 2020-06-09
  • 打赏
  • 举报
回复
输入 输出都有什么?有哪些中间数据?数量级是多少?

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧