【Mysql】X-DOC:Mysql数据库大量数据查询加速(定时JOB和存储过程应用案例)

news2024/11/19 5:46:40

X-DOC:Mysql数据库大量数据查询加速(定时JOB和存储过程应用案例)

  • 1、案例背景
  • 2、解决思路
  • 3、实现方式
    • 3.1 开启定时调度功能
    • 3.2 创建JOB日志表
    • 3.3 创建JOB任务
    • 3.4 创建JOB
    • 3.5 JOB的维护及查看
  • 4、总结

1、案例背景

在某中台系统中,设计了大量的基础数据(维度数据、维度映射关系等)来支撑业务功能,业务表中存在大量的维度外键关联字段,其优点是可以实现前端的选择录入,数据校验,确保录入数据的准确性;缺点是在做业务报表时,需要做大量的维度关联(join)操作。
受限于该平台输出报表需要写视图来实现的这一窘境,对于某些较为复杂的报表需求,可能会涉及非常多的表关联,非常影响报表性能,有的甚至需要视图套视图,由于视图数据的全量性,不会根据外部筛选条件优先过滤,更加影响执行效率,对于业务数据量大的甚至会出不来数据。

2、解决思路

引入数据仓库的解决思路,通过定时调度,提前清洗、物化数据,即将某些相对稳定,不常变化的数据,如基础数据、历史业务数据等,通过定时任务,加以必要逻辑处理后,形成中间数据、甚至是最终结果数据,保存到自建的物理表,再在表上创建合理索引,最后基于这些物理表来创建报表,提供给前端用户查询,最终能达到较好的用户体验。

3、实现方式

由于该系统是基于Mysql数据,以下以Mysql为基础,演示实现过程。

3.1 开启定时调度功能

一般关系型数据库,都有自带的定时调度功能,都可以实现定时执行脚本的功能。如SQLServer的作业,Mysql的event。

# 1、开启MYSQL定时设置
-- 1.1、通过show EVENTS显示当前定义的事件
	show EVENTS;

在这里插入图片描述
(说明:初始列表为空,图中记录为以下步骤操作完成后产生的)

-- 1.2、检查event_scheduler状态
	SHOW VARIABLES LIKE 'event_scheduler';

在这里插入图片描述

-- 1.3、设置job自动启动可以执行:
	SET GLOBAL event_scheduler = ON;
-- 或修改my.ini文件,添加:event_scheduler=1

3.2 创建JOB日志表

自定义一个张表,用来记录Job执行情况,方便后续跟踪。

delimiter #
drop procedure if exists leodb.p_job_log;
create procedure leodb.p_job_log
(
	in p_id int,
	in p_job varchar(50),
	in p_task varchar(50),
	in p_note varchar(255)
)
begin
	CREATE TABLE if not exists leodb.t_job_log (
		id 				int,			-- job id
		job 			varchar(50),	-- job名称
		task 			varchar(50),	-- 任务名称
		starttime 		datetime,		-- 开始时间
		endtime 		datetime,		-- 结束时间
		NOTE			varchar(255),	-- 备注信息
		primary key( id, job, task)
	) ENGINE=InnoDB DEFAULT CHARSET=utf8;
	-- 存在则更新结束时间,并拼接备注信息
	if exists(select 1 from leodb.t_job_log 
						where id = p_id and job = p_job and task = p_task) 
	THEN
	 	update leodb.t_job_log set
	 		endtime = now(),
			note = case when ifnull(note,'')<>'' then note + '/' + p_note else p_note end
	 	where id = p_id and job = p_job and task = p_task;
	-- 不存在则插入日志
	else
		insert into leodb.t_job_log(id, job, task, starttime, note)
		value( p_id, p_job, p_task, now(), p_note ); 
	end if;
end#
delimiter ;
-- 测试日志维护存储过程
-- call leodb.p_job_log( cast(unix_timestamp() as signed) , 'test', 'test', 'test');
-- call leodb.p_job_log( 1688086594,, 'test', 'test', 'test');

3.3 创建JOB任务

# 3、创建具体JOB存储过程
# 3.1、TASK1:维度、维度映射转存物理表
delimiter #
drop procedure if exists leodb.p_job_get_data_4_rp;
create procedure leodb.p_job_get_data_4_rp()
begin
	-- ·、成本中心映射预算部门
	start transaction;
	create table if not exists leodb.t_view_LEOPU_COST_BGDP 
	(
		s_object_code varchar(20),
		t_object_code varchar(20)
	);
	delete from leodb.t_view_LEOPU_COST_BGDP;
	insert into leodb.t_view_LEOPU_COST_BGDP 
	select s_object_code, t_object_code from leodb.view_LEOPU_COST_BGDP;
	commit;
	
	-- 2、消费类型映射预算科目
	start transaction;
	create table if not exists leodb.t_view_LEOPU_EXP_CSM_BGT
	(
		s_object_code varchar(20),
		t_object_code varchar(20)
	);
	delete from leodb.t_view_LEOPU_EXP_CSM_BGT;
	insert into leodb.t_view_LEOPU_EXP_CSM_BGT 
	select s_object_code, t_object_code from leodb.view_LEOPU_EXP_CSM_BGT;
	commit;
	
	-- 3、会计科目映射预算科目
	start transaction;
	create table if not exists leodb.t_view_LEOPU_ACC_BGT
	(
		s_object_code varchar(20),
		t_object_code varchar(20)
	);
	delete from leodb.t_view_LEOPU_ACC_BGT;
	insert into leodb.t_view_LEOPU_ACC_BGT 
	select s_object_code, t_object_code from leodb.view_LEOPU_ACC_BGT;
	commit;
	
	-- 4、LEOUP付款类型+供应商类型映射贷方(应付报账)
	start transaction;
	create table if not exists leodb.t_view_LEOPU_PUR_BILL
	(
		s1_object_code varchar(20),
		s2_object_code varchar(20),
		t_object_code varchar(20)
	);
	delete from leodb.t_view_LEOPU_PUR_BILL;
	insert into leodb.t_view_LEOPU_PUR_BILL 
	select s1_object_code, s2_object_code, t_object_code from leodb.view_LEOPU_PUR_BILL;
	commit;
end#
delimiter ;

# 3.2、TASK2:提取流程初审人到物理表
-- 基础表:记录流程初审人
select * from leodb.t_mdfp_bpm_audit_first;
drop PROCEDURE if exists leodb.p_job_task_first_audit;
create PROCEDURE leodb.p_job_task_first_audit( in p_minute int )
begin
	start transaction;
	-- 创建初审人员表
	create table if not exists leodb.t_mdfp_bpm_audit_first
	(	BUSINESS_ID varchar(32), OPERATE_TIME bigint, USER_NAME varchar(255));
	-- 创建临时表,减少对审批步骤表的访问,提升查询效率
	CREATE TEMPORARY TABLE if not exists leodb.tmp_mdfp_bpm_audit_history(
		BUSINESS_ID varchar(32), OPERATE_TIME bigint, USER_NAME varchar(255));   
	truncate table tmp_mdfp_bpm_audit_history;  
	-- 拉取最近的初审记录(增量不同:前p_minute分钟内产生的记录)
	insert into leodb.tmp_mdfp_bpm_audit_history( BUSINESS_ID, OPERATE_TIME, USER_NAME )	
	select BUSINESS_ID, OPERATE_TIME, USER_NAME
	from mdfp.mdfp_bpm_audit_history as t
	where ACT_NAME LIKE '%初审%' 
		and OPERATE_TYPE = 'approve'
		and OPERATE_TIME > UNIX_TIMESTAMP(DATE_ADD(now(),INTERVAL -p_minute MINUTE))*1000
		and not exists(select 1 from mdfp.mdfp_bpm_audit_history
										where BUSINESS_ID = t.BUSINESS_ID
											and ACT_NAME = t.ACT_NAME
											and OPERATE_TYPE = t.OPERATE_TYPE
											and OPERATE_TIME > t.OPERATE_TIME );

	-- 处理数据1:存在且时戳较大的,需要更新回去
	update leodb.t_mdfp_bpm_audit_first as d
	join leodb.tmp_mdfp_bpm_audit_history as t on d.BUSINESS_ID = t.BUSINESS_ID and t.OPERATE_TIME > d.OPERATE_TIME
	set d.OPERATE_TIME = t.OPERATE_TIME, d.USER_NAME = t.USER_NAME;					 
	-- 处理数据2:不存在的,直接插入
	insert into leodb.t_mdfp_bpm_audit_first( BUSINESS_ID, OPERATE_TIME, USER_NAME)
	select BUSINESS_ID, OPERATE_TIME, USER_NAME 
	from leodb.tmp_mdfp_bpm_audit_history as t
	where not exists(select 1 from leodb.t_mdfp_bpm_audit_first 
									 where BUSINESS_ID = t.BUSINESS_ID);

	-- 释放临时表
	drop table leodb.tmp_mdfp_bpm_audit_history;
	commit;		-- 提交事务
end;

-- 测试,由于以上存储过程,结合了同步周期考虑增量查询,此处入参写大一点,实现全量数据初始化
call leodb.p_job_task_first_audit(10000);

# 3.3、TASK3:预算存物理表
drop PROCEDURE if exists leodb.p_job_task_budget;
create PROCEDURE leodb.p_job_task_budget()
begin
	start transaction;	-- 开始事务
	-- 建表
	create table if not exists leodb.t_budget_data
	(
			FYEAR 						int,
			FMONTH 						int,
			FDATE 						date,	
			FYEARMONTH 				varchar(10),
			FBG_DEPT_CODE 		varchar(50),
			FBG_ACCOUNT_CODE 	varchar(50),
			FPROJECT_CODE 		varchar(50),
			FINDUSTRY_CODE 		varchar(50),
			BUDGET_AMOUNT 		decimal(16,6),					-- 预算金额
			OCCUPIED_AMOUNT 	decimal(16,6),				-- 占用金额
			ACTUAL_AMOUNT 		decimal(16,6),					-- 发生金额
			AVAILABLE_AMOUNT 	decimal(16,6),				-- 可用金额
			primary key(FYEAR, FMONTH, FBG_DEPT_CODE, FBG_ACCOUNT_CODE, FPROJECT_CODE, FINDUSTRY_CODE)
	)
	ENGINE=InnoDB DEFAULT CHARSET=utf8;
	-- 清除数据
	delete from leodb.t_budget_data where fyear = 2023;  
	-- 插入数据
	insert into leodb.t_budget_data( FYEAR, FMONTH, FDATE, FYEARMONTH, FBG_DEPT_CODE, FBG_ACCOUNT_CODE, 
		FPROJECT_CODE, FINDUSTRY_CODE, BUDGET_AMOUNT, OCCUPIED_AMOUNT, ACTUAL_AMOUNT, AVAILABLE_AMOUNT )
	select h.FYEAR, h.FMONTH, h.FDATE, FYEARMONTH, h.FBG_DEPT_CODE, h.FBG_ACCOUNT_CODE, 
		h.FPROJECT_CODE, h.FINDUSTRY_CODE,
		h.BUDGET_AMOUNT, h.OCCUPIED_AMOUNT, h.ACTUAL_AMOUNT, h.AVAILABLE_AMOUNT
	from leodb.view_mdfp_bm_format as h
	where fyear = 2003;
	
	COMMIT;		-- 提交事务
end;

3.4 创建JOB

# 4、创建具体JOB
delimiter #
drop event if exists leodb.JOB_RUN_EVERY1HOUR;
create event leodb.JOB_RUN_EVERY1HOUR  
on schedule every 1 hour starts timestamp '2023-06-29 00:00:01'
do
begin
	-- 1、维度数据、维度映射转存物理表
	set @v_id=cast(unix_timestamp() as signed);
	call leodb.p_job_log( @v_id , 'JOB_RUN_EVERY1HOUR', 'leodb.p_job_get_data_4_rp', '');
	call leodb.p_job_get_data_4_rp();
	call leodb.p_job_log( @v_id , 'JOB_RUN_EVERY1HOUR', 'leodb.p_job_get_data_4_rp', '维度数据转储成功');
	
	-- 2、审批步骤初审人另存物理表
	set @v_id=cast(unix_timestamp() as signed);
	call leodb.p_job_log( @v_id , 'JOB_RUN_EVERY1HOUR', 'leodb.p_job_task_first_audit(100)', '');
	call leodb.p_job_task_first_audit(100);		-- 100分钟
	call leodb.p_job_log( @v_id , 'JOB_RUN_EVERY1HOUR', 'leodb.p_job_task_first_audit(100)', '初审人员转储成功');
	
	-- 3、预算另存物理表
	set @v_id=cast(unix_timestamp() as signed);
	call leodb.p_job_log( @v_id , 'JOB_RUN_EVERY1HOUR','leodb.p_job_task_budget', '');
	call leodb.p_job_task_budget();		-- 100分钟
	call leodb.p_job_log( @v_id , 'JOB_RUN_EVERY1HOUR','leodb.p_job_task_budget', '预算数据转储成功');
end#
delimiter ;

3.5 JOB的维护及查看

# 5、JOB维护
-- 5.1、停止
ALTER EVENT leodb.JOB_RUN_EVERY1HOUR DISABLE;
-- 5.2、开启
ALTER EVENT leodb.JOB_RUN_EVERY1HOUR enable;
-- 5.3、查看状态
select * from mysql.event;

4、总结

通过以上方式的中间数据处理,可以显著提升报表查询效率。
在实际项目中,对数据实时性要求不高的场景,可以使用该方案;对于实时性要求较高的场景,也可以将数据进行分段处理,例如对于历史数据可以先行物化,仅对当前数据进行实时查询,再两者组合来加速全量数据的查询,应用得当也可以有不错的速度提升。

原创文章,转载请注明来源-X档案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/706632.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于HTML5的手术室信息管理系统的设计与实现(源码+文档+数据库)

本文通过对现有手术室信息管理系统分析&#xff0c;设计了一套基于 HTML的手术室信息管理系统&#xff0c;实现了患者信息、手术记录及术后随访等功能&#xff0c;提高了手术室工作效率。 本系统实现了患者基本资料的录入及基本信息的查询&#xff0c;提供了术前准备情况及术中…

Android Studio 下载安装教程

在我们下载前&#xff0c;先来了解一下Android的4大组件&#xff1a; 1.活动 2.服务&#xff1a;类似线程&#xff0c;听歌时跳转发信息&#xff0c;后台进行播放音乐&#xff0c;前台交互&#xff0c;后台运行任务 3.广播接收者&#xff1a;【例1】感知充电线充电进度&#xf…

【Spring Boot统一功能处理】统一异常处理,统一的返回格式,@ControllerAdvice简单分析,即将走进SSM项目的大门! ! !

前言: 大家好,我是良辰丫,在上一篇文章中我们已经学习了一些统一功能处理的相关知识,今天我们继续深入学习这些知识,主要学习统一异常处理,统一的返回格式,ControllerAdvice简单分析.&#x1f48c;&#x1f48c;&#x1f48c; &#x1f9d1;个人主页&#xff1a;良辰针不戳 &am…

邀请功能的实现分析

邀请功能 功能分析 场景&#xff1a;项目中出现用户邀请其他用户加入群组的功能 需求&#xff1a;用户点击生成邀请链接可以生成一个url&#xff0c;将这个url分享给其他用户&#xff0c;其他用户点击后对用户登录状态进行校验&#xff0c;校验通过即可加入群组&#xff0c;…

【dubbo triple provider 底层流转】

一、maven依赖 <dependency><groupId>io.netty</groupId><artifactId>netty-codec-http2</artifactId><version>4.1.90.Final</version> </dependency><dependency><groupId>org.apache.dubbo</groupId>&l…

vue3 父子组件传值 记录

最近这个组件之间传值用的较多&#xff0c;我这该死的记性&#xff0c;总给忘记写法&#xff0c;特此记录下 第一种 父传子 补充&#xff1a;LeftView.vue 是父组件&#xff1b; Video.vue 是子组件 第二种 子传父 Video.vue 子组件 第一步 引入&#xff1a; import { de…

Linux搭建Discuz论坛

环境&#xff1a;redhat 9 mysql 8 Discuz 3.5 题目要求&#xff1a;在 bbs.example.com 主机上创建 Discuz 论坛&#xff0c;数据库服务器使用 db.example.com 主机的 bbs 数据库实例&#xff0c;该实例由 MySQL数据库软件提供服务。 题目要求没有说是在一台虚拟机…

PostgreSQL学习笔记

目录 一、PostgreSQL安装 1、下载 2、安装 二、PostgreSQL操作 1、数据库操作 2、表操作 3、数据操作 一、PostgreSQL安装 本章节以windows系统安装为例&#xff0c;讲解PostgreSQL 15.0的安装过程。 1、下载 访问PostgreSQL官方网站&#xff0c;下载对应的安装包&am…

Qt/C++编写超精美自定义控件(历时9年更新迭代/超202个控件/祖传原创)

一、前言 无论是哪一门开发框架&#xff0c;如果涉及到UI这块&#xff0c;肯定需要用到自定义控件&#xff0c;越复杂功能越多的项目&#xff0c;自定义控件的数量就越多&#xff0c;最开始的时候可能每个自定义控件都针对特定的应用场景&#xff0c;甚至里面带了特定的场景的…

多元回归预测 | Matlab基于麻雀算法(SSA)优化混合核极限学习机HKELM回归预测, SSA-HKELM数据回归预测,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab基于麻雀算法(SSA)优化混合核极限学习机HKELM回归预测, SSA-HKELM数据回归预测,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 …

Idea中使用Git详细教学

目录 一、配置 Git 二、创建项目远程仓库 三、初始化本地仓库 方法一&#xff1a; 方法二&#xff1a; 四、连接远程仓库 五、提交与拉取到本地仓库 六、推送到远程仓库 七、克隆远程仓库到本地 方法一&#xff1a; 方法二&#xff1a; 八、Git分支操作 一、配置 G…

GAMES101笔记 Lecture07 Shading1(Illumination, Shading and Graphics Pipeline)

目录 Visibility / Occlusion(可见性 or 遮挡)Painters Algorithm(画家算法)Z-Buffer(深度缓冲算法) Shading(着色)A Simple Shading Model(Blinn-Phong Reflectance Model)一个简单的着色模型&#xff1a;Blinn-Phong反射模型Diffuse Reflection(漫反射) 参考资源 Visibility …

Learn Mongodb了解DB数据库 ①

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; PHP MYSQL &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &#x1f44…

flash attention论文及源码学习

​ 论文 attention计算公式如下 传统实现需要将S和P都存到HBM&#xff0c;需要占用 O ( N 2 ) O(N^{2}) O(N2)内存&#xff0c;计算流程为 因此前向HBM访存为 O ( N d N 2 ) O(Nd N^2) O(NdN2)&#xff0c;通常N远大于d&#xff0c;GPT2中N1024&#xff0c;d64。HBM带宽…

#10043. 「一本通 2.2 例 1」剪花布条(内附封面)

题目描述 原题来自&#xff1a;HDU 2087 一块花布条&#xff0c;里面有些图案&#xff0c;另有一块直接可用的小饰条&#xff0c;里面也有一些图案。对于给定的花布条和小饰条&#xff0c;计算一下能从花布条中尽可能剪出几块小饰条来呢&#xff1f; 输入格式 输入数据为多…

23年6月1日软著又面临改革,个人加分评职称和企业申报项目加分的软件著作权登记证书该如何申请?

23年6月1号&#xff0c;国家版权局对软件著作权的申请又做出了改革&#xff0c;本次改革的主要内容是全面普及线上办公。申请人无需向中心递交或邮寄登记申请纸介质材料&#xff0c;“足不出户”即可完成版权登记。 软件著作权登记实现无纸化后&#xff0c;申请人在线登记办理…

1.2g可视化大屏项目分享【包含数字孪生、视频监控、智慧城市、智慧交通等】

1.2g可视化大屏项目分享【包含数字孪生、视频监控、智慧城市、智慧交通等】 链接&#xff1a;https://pan.baidu.com/s/1KSNll7b6bVoVPPqcQmNKeQ 提取码&#xff1a;w13x

Android 图形系统-图解和初步探究

Android 图形系统-图解和初步探究_猎羽的博客-CSDN博客https://blog.csdn.net/feather_wch/article/details/131486729 Android图形系统 2023-7-1 问题&#xff1a;如何将一帧画面显示到屏幕上&#xff1f; 绘制流程 Activity代码 Window的结构 绘制流程 Activity启动后&a…

JDK 动态代理为什么只能代理有接口的类?

嗯&#xff0c;这个问题的核心本质&#xff0c;是 JDK 动态代理本身的机制来决定的。 首先&#xff0c;在 Java 里面&#xff0c;动态代理是通过 Proxy.newProxyInstance()方法来实现的&#xff0c;它需 要传入被动态代理的接口类。 之所以要传入接口&#xff0c;不能传入类&a…

MYSQL增删改语句

INSERT 语法: 单行插入 INSERT INTO table_name (column_1, column_2, ...) VALUES (value_1, value_2, ...); 多行插入 INSERT INTO table_name (column_1, column_2, ...) VALUES (value_11, value_12, ...),(value_21, value_22, ...)...; INSERT INTO 和 VALUES都是关键词 …