最近项目有个新需要,这里SQL遇到了难关,特地分享与记录。
需求: 数据汇总job
汇总当天和昨天的差异表数据,
汇总表数量(新增x张,删除x张)
数据汇总job:指的是执行一个调度任务,完成表中数据差异(其他成员完成对表对象的采集,移动数百万数据,所以这里要对表进行监控),也就是昨天的表与今天的表,俩表新增了哪些以及删除了哪些,以及增删了多少条数据。
调度任务用的是 Quartz框架,配合定时cron表达式,完成调度。项目中也做了定时任务管理界面,完成对调度任务的管理以及cron在线生成如图:
Quartz的定时任务实现可以参考一篇博客 https://blog.youkuaiyun.com/weixin_40318210/article/details/79418902
cron表达式在线生成 参考http://cron.qqe2.com/ 页面样式js等可以sou到,最近5次运行时间,用java后台可以实现。
汇总当天和昨天的差异表数据,
汇总表数量(新增x张,删除x张)重点在于sql的写法
分析:(刚开始没想明白怎么样实现,很蓝瘦):
A(昨天的表)表存在,B(今天的表)不存在 ---删除
A(昨天的表)不表存在,B(今天的表)存在 ---增加
我这里mengbi在怎样能实现俩张一样的表结构数据差异呢,baidu搜到提示用的是minus关键字可以实现查询俩一样表差异,https://www.cnblogs.com/lcword/p/5857894.html,我这里花了一下午,最后返工,因为这里minus比较了所有字段,1、sql效率低,百万数据访问导致性能降低 2字段里有时间,俩表字段有时间这个字段,时间本就是相差一天,这样查到的数据肯定不相同,所以是失败的。(理解有误,md,匹配关键字段就行了,参考博客地址) 后来我用了not in 匹配关键字,也能实现,但是效率并不高,返工,蓝瘦。最后还是用的 jion实现:
#删除 #添加
select * from (
select count(*) DEL_NUM from(
select gt2.table_name ,gt2.config_id from gather_table_20181121 gt1 left join gather_table_20181122 gt2 on
gt1.CONFIG_ID = gt2.CONFIG_ID and gt1.SERVICE_NAME = gt2.SERVICE_NAME and gt1.TABLE_USER = gt2.TABLE_USER
) where table_name is null and config_id is null ) del,
(select count(*)CRE_NUM from(
select gt1.table_name ,gt1.config_id from gather_table_20181121 gt1 right join gather_table_20181122 gt2 on
gt1.CONFIG_ID = gt2.CONFIG_ID and gt1.SERVICE_NAME = gt2.SERVICE_NAME and gt1.TABLE_USER = gt2.TABLE_USER
) where table_name is null and config_id is null ) cre
select '删除' flag ,gt1.table_name ,gt1.config_id, gt1.service_name,gt1.table_user from gather_table_20181121 gt1 left join gather_table_20181122 gt2 on
gt1.CONFIG_ID = gt2.CONFIG_ID and gt1.SERVICE_NAME = gt2.SERVICE_NAME and gt1.TABLE_USER = gt2.TABLE_USER
where gt2.table_name is null and gt2.config_id is null
union
select '添加'flag, gt2.table_name ,gt2.config_id, gt2.service_name,gt2.table_user from gather_table_20181121 gt1 right join gather_table_20181122 gt2 on
gt1.CONFIG_ID = gt2.CONFIG_ID and gt1.SERVICE_NAME = gt2.SERVICE_NAME and gt1.TABLE_USER = gt2.TABLE_USER
where gt1.table_name is null and gt1.config_id is null
select * from (select count(*) adds from gather_table_20181121 ) a,
(select count(*) del from gather_table_20181121) b
这里sql 表名我写死了,在mybatis中,将表名写成动态 ${name}来匹配表名,因为有不同日期,表名也不相同,所以这里时间拼接就ok。
ps:重新测了下sql运行时间,发现还是很慢,用了is null 匹配字段,相当于全表搜索,效率肯定底,后来优化了下用 not exist
才符合要求
select distinct '0' flag,service_name,table_name,table_user,config_id from ${tableNameYestoday} a where not exists
(select 1 from ${tableNameToday} b where b.service_name=a.service_name
and b.config_id = a.config_id and b.table_name=a.table_name and b.table_user=a.table_user)
union all
select distinct '1' flag,service_name,table_name,table_user,config_id from ${tableNameToday} a where not exists
(select 1 from ${tableNameYestoday} b where b.service_name=a.service_name
and b.config_id = a.config_id and b.table_name=a.table_name and b.table_user=a.table_user)