mysql存储过程实例

慢sql优化

当数据量太大,且需要频繁查询时,会严重影响数据库性能,查询速度也会很慢,不利于数据展示效率的提高,此时,建议在数据库中通过存储过程新建一张临时表,将需要查询的结果数据插入到临时表中,然后调度此存储过程,并设置更新时间。实现每天在库中查询一次数据到临时表,然后实时查询临时表的结果数据,来提升性能。

  • 新建存储过程,建表,每次都覆盖插入结果数据
DROP PROCEDURE IF EXISTS mysql.wukushitu_liantong;
--新建存储过程
--注1:参数根据实际情况设置,in/out不写的情况下默认为in(存储过程名后必须要加括号,及时参数为空,也要加括号)
--注2:begin与end之间写需要执行的脚本,可根据实际情况设置输出变量并赋值(也经常赋予计算逻辑)
--注3:每块脚本后都要加分号
create PROCEDURE mysql.wukushitu_liantong
(    
    OUT P_OUT_ERROR                 INT,                -- Return value:
    OUT P_OUT_ERRMSG                VARCHAR(100),       -- Return message, success or failure
    OUT P_OUT_ROWCOUNT              INT,                -- Row number Count
    IN  P_TASKID                    VARCHAR(64),        -- taskId
    IN  P_TENANTID                  VARCHAR(36)         -- TENANTID
)
BEGIN
    set P_OUT_ERROR = 0;
    set P_OUT_ERRMSG= 'Success!';
    set P_OUT_ROWCOUNT = 0;
    
-- 新建临时表
drop table if exists mysql.test_day_report;
create table mysql.test_day_report (
	DATA_DAY date DEFAULT NULL,
	PROVINCE varchar(50) DEFAULT NULL,
	CITY varchar(50) DEFAULT NULL,
	CARRIER varchar(50) DEFAULT NULL,
	YEAR varchar(20) DEFAULT NULL,
	SITE_TYPE varchar(50) DEFAULT NULL,
	SUPPLIER varchar(255) DEFAULT NULL,
	LIBRARY varchar(50) DEFAULT NULL,
	INDICATOR_CODE varchar(50) DEFAULT NULL,
	REASONS varchar(50) DEFAULT NULL,
	INDICATOR_TARGET decimal(18,0) DEFAULT NULL,
	INDICATOR_VALUE decimal(18,0) DEFAULT NULL,
	TENANTID VARCHAR(63) DEFAULT NULL,
	 PROVINCE_1 VARCHAR(63) DEFAULT NULL
	);

--添加索引
ALTER TABLE mysql.test_day_report ADD INDEX idx_tenantid ( tenantid );
	
--将结果数据插入临时表
insert  into mysql.test_day_report select a.*,d.tenantid,d.province_1 
	from 
	(
	 select
	 DATA_DAY,
	 PROVINCE,
	 CITY,
	 CARRIER,
	 YEAR,
	 SITE_TYPE,
	 SUPPLIER,
	 LIBRARY,
	 INDICATOR_CODE,
	 REASONS,
	 INDICATOR_TARGET,
	 INDICATOR_VALUE
	 from mysql.cu_site_unicom_day
	 ) a
	 left join 
	 (
	  select 
	  b.tenantid tenantid,
	  c.province_1,
	  count(b.tenantid) 
	  from 
		(
		 select 
		 TenantId,
		 City,
		 sum(case when isvaluesite='Y' then 1 else 0 end) 
		 from mysql.cwr_4libsite 
		 group by tenantid,city
		) b 
		left join 
		(
		 select 
		 tenantid,
		 left(tenantname,char_length(tenantname)-2) province_1 
		 from mysql.cwr_tenant 
		 where left(tenantname,char_length(tenantname)-2) not in('联通','电信') and left(tenantname,char_length(tenantname)-2) not like '%test%'
		) c
		on b.TenantId=c.tenantid where c.province_1 IS NOT null group by b.tenantid,c.province_1
	) d
	on a.PROVINCE=d.province_1;

END;
  • 调度存储过程
call mysql.wukushitu_liantong(@a,@b,@c,'','');#调度的时候参数必须要加@符号

老化数据保留

数据库中考虑到存储问题,有时候宽表需要设置老化周期,为避免老化后的数据查询不到的问题,可以新建存储过程,将历史数据加以保留,只替换更新新数据,以保证业务正常使用。

  • 新建存储过程,建表,首次插入结果数据
--菲律宾pldt_cell_hu存储过程
drop procedure if exists mysql.test_procedure;
create procedure mysql.test_procedure(
	OUT P_OUT_ERROR                 INT,                -- Return value:
    OUT P_OUT_ERRMSG                VARCHAR(100),       -- Return message, success or failure
    OUT P_OUT_ROWCOUNT              INT,                -- Row number Count
    IN  P_TASKID                    VARCHAR(64),        -- taskId
    IN  P_TENANTID                  VARCHAR(36)         -- TENANTID
)

BEGIN
	set P_OUT_ERROR = 0;set P_OUT_ERRMSG= 'Success!';set P_OUT_ROWCOUNT = 0;


--建表
create table if not exists mysql.test_report(
data_date date default null,
site_no varchar(255) default null,
cell_name varchar(255) default null,
band varchar(255) default null,
onair_time date default null,
pre_cell_priority varchar(255) default null,
pre_site_priority varchar(255) default null,
pre_txrx varchar(255) default null,
pre_user decimal(20,4)  default null,
pre_traffic decimal(20,4)  default null,
pre_throughput decimal(20,4)  default null,
post_cell_priority varchar(255) default null,
post_site_priority varchar(255) default null,
post_txrx varchar(255) default null,
post_user decimal(20,4)  default null,
post_traffic decimal(20,4)  default null,
post_throughput decimal(20,4)  default null,
user_gain decimal(20,4)  default null,
traffic_gain decimal(20,4)  default null,
throughput_gain decimal(20,4)  default null,
solution varchar(255) default null
);

--添加联合主键,为替换更新建立参考字段
alter table mysql.test_report add primary key(site_no,cell_name);

--首次插入数据
insert into mysql.test_report
select 
m.*,
z.cell_priority pre_cell_priority,          
z.site_priority pre_site_priority,
z.txrx pre_txrx,                              
z.rrc_user pre_user,                 
z.payload pre_traffic,                  
z.lte_dl_user_throughput_kbps pre_throughput,
w.cell_priority post_cell_priority,          
w.site_priority post_site_priority,
w.txrx post_txrx,          
w.rrc_user post_user,                 
w.payload post_traffic,                  
w.lte_dl_user_throughput_kbps post_throughput,
(w.rrc_user-z.rrc_user)/z.rrc_user*100 user_gain,
(w.payload-z.payload)/z.payload*100 traffic_gain,
(w.lte_dl_user_throughput_kbps-z.lte_dl_user_throughput_kbps)/z.lte_dl_user_throughput_kbps*100 throughput_gain,
case when w.sector_priority IN("prio1-Critical", "prio2-high util", "prio3-Warning") then "fail" ELSE "passed" END solution 
from
(select                 
y.data_date, 
x.site_no site_no,
x.cell_name cell_name,                                                                      
y.band,                     
x.onair_time onair_time
from 
(select max(date(a.extFiled36)) onair_time,b.site_no,b.sector_name,b.cell_name 
from mysql.test_attr a,mysql.test_request b where a.requestId=b.requestId and a.extFiled36<>'' group by b.site_no,b.sector_name,b.cell_name) x
left join
(select
data_date,
site_no,
cell_name,             
band from mysql.test) y
on x.site_no=y.site_no and x.cell_name=y.cell_name
where datediff(x.onair_time,y.data_date)>=0 and datediff(x.onair_time,y.data_date)<7) m
left join
(select               
data_date, 
site_no site_no,
cell_name cell_name,                                              
cell_priority,          
site_priority,                        
band,                     
txrx,          
sum(rrc_user) rrc_user,                 
sum(payload) payload,                  
sum(lte_dl_user_throughput_kbps) lte_dl_user_throughput_kbps
from mysql.test group by data_date,site_no,cell_name,cell_priority,site_priority,band,txrx) z
on z.site_no=m.site_no and z.cell_name=m.cell_name and z.data_date=date_add(m.data_date,interval -7 day)
left join
(select               
data_date, 
site_no site_no,
cell_name cell_name,                                              
cell_priority,          
site_priority,                        
band,                     
txrx,         
sum(rrc_user) rrc_user,                 
sum(payload) payload,                  
sum(lte_dl_user_throughput_kbps) lte_dl_user_throughput_kbps
from mysql.test group by data_date,site_no,cell_name,cell_priority,site_priority,band,txrx) w
on w.site_no=m.site_no and w.cell_name=m.cell_name and w.data_date=date_add(m.data_date,interval 14 day);

end
  • 调度存储过程,使新建的表生效
call mysql.test_procedure(@a,@b,@c,'','');
  • 新建存储过程,替换更新有变化的新数据,保留没变化的历史数据
--数据更新存储过程
drop procedure if exists mysql.test_procedure_update;
create procedure mysql.test_procedure_update(
	OUT P_OUT_ERROR                 INT,                -- Return value:
    OUT P_OUT_ERRMSG                VARCHAR(100),       -- Return message, success or failure
    OUT P_OUT_ROWCOUNT              INT,                -- Row number Count
    IN  P_TASKID                    VARCHAR(64),        -- taskId
    IN  P_TENANTID                  VARCHAR(36)         -- TENANTID
)

BEGIN
	set P_OUT_ERROR = 0;set P_OUT_ERRMSG= 'Success!';set P_OUT_ROWCOUNT = 0;

--更新存在新onair_time的小区数据,保留无新onair_time的小区数据
replace into mysql.test_report 
select 
m.*,
z.cell_priority pre_cell_priority,          
z.site_priority pre_site_priority,
z.txrx pre_txrx,                              
z.rrc_user pre_user,                 
z.payload pre_traffic,                  
z.lte_dl_user_throughput_kbps pre_throughput,
w.cell_priority post_cell_priority,          
w.site_priority post_site_priority,
w.txrx post_txrx,          
w.rrc_user post_user,                 
w.payload post_traffic,                  
w.lte_dl_user_throughput_kbps post_throughput,
(w.rrc_user-z.rrc_user)/z.rrc_user*100 user_gain,
(w.payload-z.payload)/z.payload*100 traffic_gain,
(w.lte_dl_user_throughput_kbps-z.lte_dl_user_throughput_kbps)/z.lte_dl_user_throughput_kbps*100 throughput_gain,
case when w.sector_priority IN("prio1-Critical", "prio2-high util", "prio3-Warning") then "fail" ELSE "passed" END solution 
from
(select                 
y.data_date, 
x.site_no site_no,
x.cell_name cell_name,                                                                      
y.band,                     
x.onair_time onair_time
from 
(select max(date(a.extFiled36)) onair_time,b.site_no,b.sector_name,b.cell_name 
from mysql.test_attr a,mysql.test_request b where a.requestId=b.requestId and a.extFiled36<>'' group by b.site_no,b.sector_name,b.cell_name) x
left join
(select
data_date,
site_no,
cell_name,             
band from mysql.test) y
on x.site_no=y.site_no and x.cell_name=y.cell_name
where datediff(x.onair_time,y.data_date)>=0 and datediff(x.onair_time,y.data_date)<7) m
left join
(select               
data_date, 
site_no site_no,
cell_name cell_name,                                              
cell_priority,          
site_priority,                        
band,                     
txrx,          
sum(rrc_user) rrc_user,                 
sum(payload) payload,                  
sum(lte_dl_user_throughput_kbps) lte_dl_user_throughput_kbps
from mysql.test group by data_date,site_no,cell_name,cell_priority,site_priority,band,txrx) z
on z.site_no=m.site_no and z.cell_name=m.cell_name and z.data_date=date_add(m.data_date,interval -7 day)
left join
(select               
data_date, 
site_no site_no,
cell_name cell_name,                                              
cell_priority,          
site_priority,                        
band,                     
txrx,         
sum(rrc_user) rrc_user,                 
sum(payload) payload,                  
sum(lte_dl_user_throughput_kbps) lte_dl_user_throughput_kbps
from mysql.test group by data_date,site_no,cell_name,cell_priority,site_priority,band,txrx) w
on w.site_no=m.site_no and w.cell_name=m.cell_name and w.data_date=date_add(m.data_date,interval 14 day)
--若中间表中已存在基础表中最新的cell_name和onair_time,则不操作(保留原始数据,以防宽表老化后查询不到),否则以site_no与cell_name为主键,替换成最新的数据
where not exists (select n.onair_time,n.cell_name from mysql.test_report n
where concat(m.onair_time,m.cell_name)=concat(n.onair_time,n.cell_name));

END
  • 调度存储过程,实现数据更新
call mysql.test_procedure_update(@a,@b,@c,'','');
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值