MySQL实现每分钟扫描一次数据库,查找16分钟前的记录和15分钟 以前-16分钟的记录

描述

每分钟扫描一次数据库,查找15分钟 以前-16分钟的记录。
先从send_ orders获取符合条件的记录,并提取master_ id字段的值与order_id的值
然后从master has_ slave表里根据上一步得到的master _id值 查找匹配的slave_ id的值
用上一步得到的slave _id与第一步得到的master_ id及order_ id组合 的记录去recive_order里查找master_ id, slave__id, order_ id这三者有没有一样的,如果没有找到就在faile_ order_ id里插入数据: master_ id,slave_ id,order_ id

实现如下:

1.查找16分钟前的记录

-- 解决方案
1.建立封存表存储faile_order_id表每分钟时的状态
 CREATE TABLE faile_order_id_seal(
master_id VARCHAR(36) PRIMARY KEY,
order_id VARCHAR(36),
slave_id VARCHAR(36),
run_time DATE --执行存储过程的时间
) ENGINE=INNODB;

2.建立存储过程
DROP PROCEDURE IF EXISTS proc_test;
CREATE PROCEDURE  proc_test(
v_run_time DATE, --执行时间
v_num INT -- 删除距离现在天数以前的数据
)
BEGIN
-- 插入匹配不到的数据于封存表中
 INSERT INTO faile_order_id_seal(master_id,order_id,slave_id,run_time)
 SELECT ro.master_id,ro.order_id,ro.slave_id,v_run_time
 From recive_order ro 
   LEFT JOIN 
    (SELECT so.master_id,so.order_id,(SELECT slave_id FROM master_has_slave WHERE master_id=so.master_id) slave_id
     From send_orders so) a 
   ON ro.master_id=a.master_id AND ro.order_id=a.order_id AND ro.slave_id=a.slave_id
 WHERE ro.master_id IS NULL;
 -- 当然由于执行评率过高,可删除较久的数据
 DELETE FROM  faile_order_id_seal WHERE TIMESTAMPDIFF(Minute,run_time,Now())>=v_num;
END;

3.添加存储过程于事件中,设置每分钟运行一次存储过程(确保开启事件: SET GLOBAL evet_scheduler=ON)
CREATE EVENT IF NOT EXISTS evt_instert_faile_order_id
ON schedule EVERY 1 MINUTE STARTS '2020-04-04 18:57:00'
ON Completion Preserve Enable
DO CALL proc_test(now(),20);

4.查询16分钟前faile_order_id_seal表的数据
SELECT * FROM faile_order_id_seal WHERE TIMESTAMPDIFF(Minute,run_time,Now())=16;

2.,查找15分钟 以前-16分钟的记录(即只查找每一分钟增加的数据)

-- 解决方案
-- 1.建立封存表存储faile_order_id表每分钟时的状态
CREATE TABLE faile_order_id_seal(
master_id VARCHAR(36) PRIMARY KEY,
order_id VARCHAR(36),
slave_id VARCHAR(36),
run_time DATE --存储执行存储过程的时间
) ENGINE=INNODB;

-- 2.存储每分钟执行时的新增数据
CREATE TABLE faile_order_id_num(
master_id VARCHAR(36) PRIMARY KEY,
order_id VARCHAR(36),
slave_id VARCHAR(36),
run_time DATE --执行存储过程的时间
) ENGINE=INNODB;

-- 3.建立存储过程
DROP PROCEDURE IF EXISTS proc_test;
CREATE PROCEDURE  proc_test(
v_run_time DATE, --执行时间
v_num INT -- 删除距离现在天数以前的数据
)
SQL SECURITY INVOKER
BEGIN
-- 建立封存表存储faile_order_id临时表存储封存表上一分钟的数据
 DROP TEMPORARY TABLE IF EXISTS temp_faile_order_id;
 CREATE TEMPORARY TABLE temp_faile_order_id(
master_id  VARCHAR(36) PRIMARY KEY,
order_id VARCHAR(36),
slave_id VARCHAR(36),
run_time DATE --存储执行存储过程的时间
) ENGINE=MEMORY;

-- 插入匹配不到的数据于封存表中
 INSERT INTO faile_order_id_seal(master_id,order_id,slave_id,run_time)
 SELECT ro.master_id,ro.order_id,ro.slave_id,v_run_time
 FROM recive_order ro 
   LEFT JOIN 
    (SELECT so.master_id,so.order_id,(SELECT slave_id FROM master_has_slave WHERE master_id=so.master_id) slave_id
     FROM send_orders so) a 
   ON ro.master_id=a.master_id AND ro.order_id=a.order_id AND ro.slave_id=a.slave_id
 WHERE ro.master_id IS NULL;
 
 -- 插入封存表上一分钟的数据于临时表
 INSERT INTO temp_faile_order_id(master_id,order_id,slave_id,run_time)
   SELECT fs.master_id,fs.order_id,fs.slave_id,fs.run_time
   FROM faile_order_id_seal fs
 WHERE TIMESTAMPDIFF(Minute,fs.run_time,Now())=1;

  -- 如临时表存在数据则插入faile_order_id_num表数据
 IF EXISTS (SELECT 1 FROM temp_faile_order_id LIMIT 1) THEN
 --存储每分钟新增数据
  INSERT INTO faile_order_id_num(master_id,order_id,slave_id,run_time)
  SELECT fs.master_id,fs.order_id,hs.slave_id,fs.run_time
  FROM faile_order_id_seal fs
     LEFT JOIN (SELECT master_id FROM temp_faile_order_id) a  ON a.master_id=fs.master_id
  WHERE fs.master_id IS NULL;
 END IF; 
 
 -- 当然由于执行评率过高,可删除较久的数据
 DELETE FROM  faile_order_id_seal WHERE TIMESTAMPDIFF(Minute,run_time,Now())>=v_num;
 DELETE FROM  faile_order_id_num WHERE TIMESTAMPDIFF(Minute,run_time,Now())>=v_num;
 DROP TEMPORARY TABLE IF EXISTS temp_faile_order_id;
END;

-- 4.添加存储过程于事件中,设置每分钟运行一次存储过程(确保开启事件: SET GLOBAL evet_scheduler=ON)
CREATE EVENT IF NOT EXISTS evt_instert_faile_order_id
ON schedule EVERY 1 MINUTE STARTS '2020-04-04 18:57:00'
ON Completion Preserve Enable
DO CALL proc_test(now(),20);

-- 5.查询15分钟前到16分钟那一分钟faile_order_id_num新增的数据
SELECT * FROM faile_order_id_num WHERE TIMESTAMPDIFF(Minute,run_time,Now())=16;

3.上述部分脚本语句改写

-- 原SQL脚本
SELECT ro.master_id,ro.order_id,ro.slave_id,v_run_time
 FROM recive_order ro 
   LEFT JOIN 
    (SELECT so.master_id,so.order_id,(SELECT slave_id FROM master_has_slave WHERE master_id=so.master_id) slave_id
     FROM send_orders so) a 
   ON ro.master_id=a.master_id AND ro.order_id=a.order_id AND ro.slave_id=a.slave_id
 WHERE ro.master_id IS NULL;
 
 -- 利用LEFT JOIN 替代标量子查询,如下所示
 SELECT ro.master_id,ro.order_id,ro.slave_id,v_run_time
 FROM recive_order ro 
   LEFT JOIN 
    (SELECT so.master_id,so.order_id,b.slave_id
     FROM send_orders so
       LEFT JOIN (SELECT master_id,slave_id FROM master_has_slave) b ON so.master_id=b.master_id
     ) a 
   ON ro.master_id=a.master_id AND ro.order_id=a.order_id AND ro.slave_id=a.slave_id
 WHERE ro.master_id IS NULL;
++a
发布了13 篇原创文章 · 获赞 0 · 访问量 1079

猜你喜欢

转载自blog.csdn.net/qq_40881607/article/details/105318065
今日推荐