MySQL存储过程删除历史数据

需求:MySQL百万数据的数据表table1中对应每个column_1,每10分钟存储一个数据,需改为每1小时存储一个数据,冗余的删掉,即每6条保留1条数据。

初版存储过程如下:

DELIMITER //
DROP PROCEDURE IF EXISTS p_test //
CREATE PROCEDURE p_test() 
BEGIN
	DECLARE done INT DEFAULT FALSE;
	DECLARE field_1 INT (11);
	DECLARE p1 INT(11);
	DECLARE cur_list CURSOR FOR SELECT id FROM table1 WHERE column_1 = 'column name';
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;	
	OPEN cur_list;
	SET p1 = 1;	
	loop1 : LOOP
		FETCH cur_list INTO field_1;
		IF done THEN LEAVE loop1; 
		END IF;
		IF p1 < 7 THEN 
			SET @sql_delete = CONCAT("delete from table1 where id = ", field_1 );
			PREPARE sqlli FROM @sql_delete;
			EXECUTE sqlli;
			COMMIT;
		ELSE
			SET p1 = 1;
		END IF;
		SET p1 = p1 + 1;
	END LOOP loop1;
	CLOSE cur_list;
END //
DELIMITER; //

call p_test;

也没什么特别的,column name直接写死,做了个变量p1,根据p1在循环中的递增情况实现删除数据1-5,保留第6个,p1退回到1,再次循环。

因为column name写死很不方便,想给存储过程传参,传参是字符串String类型,游标取值和之前略有不同:

DELIMITER //
DROP PROCEDURE IF EXISTS p_test //
CREATE PROCEDURE p_test(IN column1 VARCHAR(256)) 
BEGIN
	DECLARE done INT DEFAULT FALSE;
	DECLARE field_1 INT (11);
	DECLARE p1 INT(11);
	
#定义游标	
	DECLARE cur_list CURSOR FOR (SELECT * from view_1);
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
	
#采用视图
	DROP VIEW IF EXISTS view_1;
#动态sql
	SET @strSql = "CREATE VIEW view_1 as SELECT id FROM table1";
	IF column1 IS NOT NULL THEN
		SET @strSql = CONCAT(@strSql, " WHERE column_1 = '", column1,"'");
  END IF;
	PREPARE stmt FROM @strSql;  
  EXECUTE stmt;  
  DEALLOCATE PREPARE stmt; 
	
	OPEN cur_list;
	SET p1 = 1;	
	loop1 : LOOP
		FETCH cur_list INTO field_1;
		IF done THEN LEAVE loop1; 
		END IF;
		IF p1 < 7 THEN 
			SET @sql_delete = CONCAT("delete from table1 where id = ", field_1);
			PREPARE sqlli FROM @sql_delete;
			EXECUTE sqlli;
			COMMIT;
		ELSE
			SET p1 = 1;
		END IF;
		SET p1 = p1 + 1;
	END LOOP loop1;
	CLOSE cur_list;
END //
DELIMITER; //
call p_test("column name");

每次创建存储过程之后,采用 show procedure status; 判断存储过程是否已创建。

...the right syntax to use near NULL at line 1, 出现在调用存储过程的时候报错,传参的读取有可能为NULL,当使用PREPARE的时候会报错,检查CONCAT拼接,完善@strSQL

因数据量过大,考虑在外层做了一个关于column_1的筛选,找出所有数据量超过10000的column name,类似于:

SELECT column_1, count(*) as col_count FROM table1 group by column_1 having col_count > 10000

然后将筛选出的具体column name,调用第一个存储过程进行数据清理,新加的存储过程如下:

delimiter //
DROP PROCEDURE IF EXISTS p_test2//
CREATE PROCEDURE p_test2(IN num INT(11)) 
BEGIN
	DECLARE done INT DEFAULT FALSE;
	DECLARE field_1 VARCHAR(256);
	DECLARE field_2 INT(11);
#定义游标	
	DECLARE cur CURSOR FOR (SELECT * from view2);
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
#采用视图
	DROP VIEW IF EXISTS view2;
#动态sql
	SET @strSql = "CREATE VIEW view2 as SELECT column_1, count(*) as col_count FROM table1 group by column_1";
	IF num IS NOT NULL THEN
		SET @strSql = CONCAT(@strSql, " HAVING col_count > ", num);
  END IF;
	PREPARE stmt FROM @strSql;  
  EXECUTE stmt;  
  DEALLOCATE PREPARE stmt; 
	
	OPEN cur;
	loop2 : LOOP
		FETCH cur INTO field_1, field_2;
		IF done THEN LEAVE loop2; 
		END IF;
		call p_test(field_1);
	END LOOP loop2;
	CLOSE cur;
END //
delimiter; //
call p_test2(10000);

Incorrect number of FETCH variables,出现在游标select字段与fetch into不匹配,改为field_1, field_2之后成功运行

至此,百万数据表中根据column name实现每6条保留1条的数据清理基本实现,实际执行,清理一个万级数据的column name耗时约2分钟

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MySQL所有支持的存储引擎包括: 1. InnoDB:这是MySQL的默认存储引擎。它支持事务、行级锁和外键等特性。 2. MyISAM:这是MySQL中较早的存储引擎之一。它不支持事务和行级锁,但是具有高性能和压缩特性。 3. Memory:这个存储引擎将所有数据存储在内存中,因此速度非常快。但是,数据不会持久化,这意味着在重启服务器后,数据将会丢失。 4. CSV:这个存储引擎将数据存储在逗号分隔的文件中。它对于导入和导出数据非常方便,但不支持索引和事务等功能。 5. Blackhole:这个存储引擎不会实际存储数据,它只是将写入的数据转发到其他MySQL服务器上。因此,它适用于日志记录和数据分发等应用场景。 6. Merge:这个存储引擎允许将多个MyISAM表合并成一个虚拟表,使查询变得更加方便。 7. Federated:这个存储引擎允许将数据存储在远程服务器上,而在本地服务器上查询数据,使得数据分布式管理变得更加容易。 除此之外,还有一些其他的存储引擎,如Archive、Example、NDB Cluster、Partition等。不同的存储引擎具有不同的特点和应用场景,开发者可以根据实际需求选择适合的存储引擎。 ### 回答2: MySQL是一款常见的关系型数据库管理系统,提供了多种存储引擎供用户选择。以下是MySQL中常见的几种存储引擎: 1. InnoDB引擎:InnoDB是MySQL的默认存储引擎,支持事务处理和行级锁定。它具有高度的可靠性和稳定性,支持崩溃恢复和多版本并发控制(MVCC)等特性。 2. MyISAM引擎:MyISAM是MySQL最早的存储引擎,它支持全文索引和表级锁定,但不支持事务处理。它在读操作上性能较好,适用于读多写少的场景。 3. Memory引擎:Memory引擎将数据存储在内存中,因此读写速度非常快,适用于对速度要求较高的应用。但它的数据是临时存储的,当数据库关闭时数据会丢失。 4. Archive引擎:Archive引擎适用于大量历史数据的存储,它具有高度的压缩比和快速的插入速度,但不支持更新和删除操作。 5. CSV引擎:CSV引擎以纯文本形式存储数据,采用逗号分隔值的格式。它对于导入和导出数据非常方便,但不支持索引、事务等功能。 6. Blackhole引擎:Blackhole引擎不会实际存储数据,它只接受写操作并将数据丢弃。这在复制和分发数据时非常有用。 除了以上几种常见的存储引擎外,MySQL还提供了其他一些存储引擎,如FederatedX引擎、Merge引擎等,它们具有各自的特点和适用场景。根据实际需求,用户可以选择合适的存储引擎来优化数据库的性能和功能。 ### 回答3: MySQL是一个关系型数据库管理系统,内部提供了多种存储引擎来支持数据存储和查询。以下是MySQL的一些常见存储引擎: 1. InnoDB:这是MySQL默认的存储引擎,也是最常用的引擎之一。它支持事务、行级锁定和外键约束等功能,适用于大部分的应用场景。 2. MyISAM:这是另一种常见的存储引擎,主要用于读密集型的应用。它不支持事务和行级锁定,但它的查询性能很高。 3. Memory:这个存储引擎将数据存储在内存中,速度非常快,但数据不会持久化。适用于缓存和临时数据存储。 4. Archive:这个存储引擎用于高度压缩的只读数据。它对于大量历史数据的存储非常有效,但写入和查询速度较慢。 5. CSV:这个存储引擎将数据存储为逗号分隔值文件,适用于导入和导出数据。 6. Blackhole:这个存储引擎直接丢弃所有写入数据,对于备份和复制很有用。 7. NDB:这是一个高度可扩展的存储引擎,适用于分布式数据库和高并发应用。 8. Federated:这个存储引擎可以将数据保存在远程服务器上,允许在多个数据库之间共享数据。 以上列出的存储引擎只是MySQL提供的一部分,每个存储引擎都有自己的特性和适用场景。选择合适的存储引擎取决于应用的需求和性能要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值