Mysql 타이밍 + 저장 프로시저를 사용하여 임시 테이블 통계 생성

1. mysql 타이밍 작업에 대한 간략한 소개

mysql의 timed task는 이벤트(event)를 이용하여 구현되는데, mysql 5.1.6 버전부터 매초 정확하게 task를 실행할 수 있는 event scheduler(event scheduler)라는 기능이 추가되었다. 상대적으로 높은 성능을 요구하는 장면에서 매우 유용합니다.다음으로 타이밍 통계를 구현하기 위해 mysql의 이벤트 이벤트를 사용하겠습니다.

2. 준비사항

(1) 타이밍 정책이 활성화되어 있는지 확인

show variables like '%event_sche%';

실행 결과는 다음과 같습니다

ON이면 열린 상태, OFF이면 닫힌 상태, 닫힌 상태라고 가정하면 다음 SQL 문을 사용하여 열고 닫습니다.

--开启定时调度策略(下面两个语句都可以)
set global event_scheduler=1;
set global event_scheduler = on;

--关闭定时调度策略(下面两个语句都可以)
set global event_scheduler=0;
set global event_scheduler = off;

타이밍 스케줄링 전략 SQL 실행 결과를 끕니다.

타이밍 스케줄링 전략 SQL 실행 결과 활성화:

(2) 사용자 정보 테이블 및 사용자 주문 테이블 sql 스크립트 실행

# 用户信息表
CREATE TABLE `user_info` (
    `id` INT ( 11 ) NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `name` VARCHAR ( 30 ) NOT NULL COMMENT '用户名',
    `phone` VARCHAR ( 11 ) NOT NULL COMMENT '手机号',
    `status` TINYINT ( 1 ) NULL DEFAULT NULL COMMENT '用户状态:停用0,启动1',
    `create_time` datetime NOT NULL COMMENT '创建时间',
    PRIMARY KEY ( `id` ) USING BTREE 
) ENGINE = INNODB AUTO_INCREMENT = 10001 CHARACTER 
SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户信息表';

# 用户订单表
CREATE TABLE `user_order`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `order_num` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编号',
  `user_id` int(11) NOT NULL COMMENT '用户ID',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `idx_order_num`(`order_num`) USING BTREE COMMENT '订单编号唯一'
) ENGINE = INNODB AUTO_INCREMENT = 10001 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户订单表';

(3) 테스트 데이터 삽입을 위한 sql 스크립트 실행

# 向用户信息表中插入三条测试数据
INSERT INTO `user_info` (`id`, `name`, `phone`, `status`, `create_time`) VALUES (10001, '张三', '13900669010', 1, '2023-03-14 17:01:42');
INSERT INTO  `user_info` (`id`, `name`, `phone`, `status`, `create_time`) VALUES (10002, '李四', '13900669111', 1, '2023-03-14 17:01:42');
INSERT INTO  `user_info` (`id`, `name`, `phone`, `status`, `create_time`) VALUES (10003, '王五', '13900669876', 1, '2023-03-14 17:01:42');

# 向用户订单表中插入八条测试数据
INSERT INTO  `user_order` (`id`, `order_num`, `user_id`, `create_time`) VALUES (10001, 'dingdan001', 10002, '2023-03-14 17:03:40');
INSERT INTO  `user_order` (`id`, `order_num`, `user_id`, `create_time`) VALUES (10002, 'dingdan002', 10003, '2023-03-14 17:03:40');
INSERT INTO  `user_order` (`id`, `order_num`, `user_id`, `create_time`) VALUES (10003, 'dingdan003', 10002, '2023-03-14 17:03:40');
INSERT INTO  `user_order` (`id`, `order_num`, `user_id`, `create_time`) VALUES (10004, 'dingdan004', 10002, '2023-03-14 17:03:40');
INSERT INTO  `user_order` (`id`, `order_num`, `user_id`, `create_time`) VALUES (10005, 'dingdan005', 10003, '2023-03-14 17:03:40');
INSERT INTO  `user_order` (`id`, `order_num`, `user_id`, `create_time`) VALUES (10006, 'dingdan006', 10003, '2023-03-14 17:03:40');
INSERT INTO  `user_order` (`id`, `order_num`, `user_id`, `create_time`) VALUES (10007, 'dingdan007', 10002, '2023-03-14 17:03:40');
INSERT INTO  `user_order` (`id`, `order_num`, `user_id`, `create_time`) VALUES (10008, 'dingdan008', 10001, '2023-03-14 17:03:40');

(2) (3)의 스크립트 실행 결과:

3. 저장 프로시저 스크립트 작성


DELIMITER //
DROP PROCEDURE
IF
    EXISTS statistics_user_order // CREATE PROCEDURE statistics_user_order () BEGIN
    DECLARE
        temp_table_name VARCHAR ( 60 ) DEFAULT '';
    DECLARE
        suffix VARCHAR ( 10 ) DEFAULT '';
    DECLARE
        old_table_name VARCHAR ( 60 ) DEFAULT NULL;
    SELECT
        table_name INTO old_table_name 
    FROM
        information_schema.`TABLES` 
    WHERE
        table_name LIKE 'temp_statistics_%' 
        AND table_schema = 'db_name'; -- 此处填自己对应的数据库名即可
    IF
        old_table_name IS NOT NULL THEN
        -- execute multiple statements
        -- 如果IF THEN ... END IF块内有多个语句,最好将它们放在一个BEGIN ... END;块中
        BEGIN
                
                SET @drop_sql := CONCAT( 'DROP TABLE ', old_table_name, ';' );
            PREPARE d_sql 
            FROM
                @drop_sql;
            EXECUTE d_sql;
            DEALLOCATE PREPARE d_sql;
            
        END;
        
    END IF;
    SELECT
        DATE_FORMAT( NOW(), '%Y%m%d' ) INTO suffix;
    
    SET temp_table_name = CONCAT( 'temp_statistics_', suffix );
    
    SET @create_sql = CONCAT( 'create table if not exists ', temp_table_name, "(
        `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
        `user_id` INT ( 11 ) NOT NULL COMMENT '用户ID',
        `name` VARCHAR ( 30 ) NOT NULL COMMENT '用户名',
        `number` INT ( 11 ) NOT NULL DEFAULT 0 COMMENT '订单数',
        `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
        PRIMARY KEY ( `id` ) USING BTREE 
    ) ENGINE = INNODB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户订单统计表';" );
    PREPARE pre_stmt 
    FROM
        @create_sql;
    EXECUTE pre_stmt;
    DEALLOCATE PREPARE pre_stmt;
    -- 简单的用set或者declare语句定义变量,然后直接作为sql的表名是不行的,mysql会把变量名当作表名。
    SET @insert_sql = CONCAT( 'INSERT INTO ', temp_table_name, "( `user_id`, `name`, `number` ) SELECT
        i.id AS `user_id`,
        i.`name` AS `name`,
        COUNT( o.user_id ) AS `number` 
        FROM
        user_info i
        LEFT JOIN user_order o ON i.id = o.user_id 
        WHERE
        i.`status` = 1 
        GROUP BY
    i.id;" );
    PREPARE pre_insert 
    FROM
        @insert_sql;
    EXECUTE pre_insert;
    DEALLOCATE PREPARE pre_insert;
    
END // 
DELIMITER;

스크립트 실행 결과: (참고: 위의 저장 프로시저 "AND table_schema = 'db_name'; -- 여기에 해당 데이터베이스 이름을 입력하십시오"에서 데이터베이스를 변경하는 것을 잊지 마십시오.)

위의 저장 프로세스는 주로 세 단계로 나뉩니다.

a. 데이터베이스에 임시 테이블이 존재하는지 확인하고, 존재하는 경우 테이블 구조를 삭제(이전 테이블 제거)

b. 현재 시간에 따라 새 임시 테이블을 만들고 통계적 필요에 따라 테이블 구조에 필드를 추가합니다.

c. 공동 테이블 쿼리, 각 사용자가 소유한 주문 수를 세고 임시 테이블에 삽입

4. 예약된 작업 스크립트 작성 및 실행

모든 사람이 더 큰 효과를 볼 수 있도록 예약 작업을 10초마다 실행하도록 설정합니다. 즉, 이 예약 작업의 기능은 10초마다 사용자의 주문 수를 세는 것입니다.

create event job_statistics -- 是创建名为job_statistics的事件;
on schedule every 10 SECOND -- 创建周期定时的规则,意思是每10s种执行一次;
on completion preserve enable --  是表示创建后就开始生效,不让开始生效设置disable
do call statistics_user_order(); -- 事件要执行的内容,调用了上述的存储过程

스크립트 실행 결과:

예약된 작업 보기:

select * from information_schema.EVENTS;

스크립트 실행 결과:

예약된 작업의 실행 효과 보기: (아래 시차 참조, 타이밍이 새로워짐)

타이밍 작업 실행 중지:

ALTER event job_statistics on completion preserve disable;

타이밍 작업 계속:

ALTER event job_statistics on completion preserve enable;

추천

출처blog.csdn.net/weixin_42218169/article/details/129565173