博客
关于我
MySQL-存储过程-高效清理数据
阅读量:459 次
发布时间:2019-03-06

本文共 2299 字,大约阅读时间需要 7 分钟。

如何在存储过程中合理利用索引清理数据

在存储过程中清理数据时,往往会引起全表扫,如果表内数据非常大,清理效率会很低。以下将讲解如何在存储过程中合理利用索引清理数据。

一、准备表结构(测试数据量740W)

以下是用于测试的表结构:

CREATE TABLE `test`.`procedure_test` (  `pk` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',  `data_time` varchar(100) DEFAULT NULL COMMENT '数据时间,格式:2020-07-21 23:00:36',  `altitude` double DEFAULT NULL COMMENT '海拔高度 (单位米)',  `lat` double DEFAULT NULL COMMENT '纬度',  `lon` double DEFAULT NULL COMMENT '经度',  `derection` bigint(20) DEFAULT NULL COMMENT '方向 0-359 单位° ;正北为0,顺时针',  `statecode` varchar(100) DEFAULT NULL COMMENT '状态信息',  PRIMARY KEY (`pk`),  KEY `idx_data_time` (`data_time`)) COMMENT='存储过程清理数据测试表';

二、错误示范

以下是一个常见的错误示范:

-- 清理3天前的数据CREATE DEFINER=`my_admin`@`%` PROCEDURE `test`.`p_procedure_test_delete_3day_ago`()BEGINdelete from test.procedure_test where data_time < (CURRENT_TIMESTAMP() + interval - 3 day);END

三、错误解法

以下是一个常见的错误解法:

-- 清理3天前的数据CREATE DEFINER=`my_admin`@`%` PROCEDURE `test`.`p_procedure_test_delete_3day_ago`()BEGINDECLARE before_dt datetime;select (CURRENT_TIMESTAMP() + interval - 3 day) into before_dt;delete from test.procedure_test where data_time < before_dt;END

四、正确示范

以下是一个正确的解决方案:

-- 清理3天前的数据CREATE DEFINER=`my_admin`@`%` PROCEDURE `test`.`p_procedure_test_delete_3day_ago`()BEGINDECLARE before_dt datetime;DECLARE delete_sql varchar(1024);select (CURRENT_TIMESTAMP() + interval - 3 day) into before_dt;set delete_sql = CONCAT("delete from test.procedure_test where data_time < '",before_dt,"'");set @dlt = delete_sql;prepare dlt from @dlt;execute dlt;deallocate prepare dlt;END

原理解析

  • 错误示范中,由于在 where 条件中直接调用了函数 (CURRENT_TIMESTAMP() + interval - 3 day),导致删除语句无法正确使用索引,从而引发了全表扫,以下是 explain 语句的结果:
  • id select_type table type possible_keys key key_len ref rows Extra
    1 SIMPLE procedure_test ALL idx_data_time NULL NULL NULL 7403414 Using where
    1. 错误解法,试图通过变量的形式来执行,但结果与上述一致,无法正确利用索引提高效率。

    2. 正确示范中,通过使用 prepare 来执行动态语句,成功解决了问题,以下是 explain 语句的结果:

    3. id select_type table type possible_keys key key_len ref rows Extra
      1 SIMPLE procedure_test range idx_data_time idx_data_time 303 NULL 311888 Using index condition
      1. 成功使用索引后,执行效率大大提高,从全表扫 (7403414) 到使用索引 (311888)。

      2. 结合 event 定时任务使用:

      3. CREATE EVENT e_procedure_test_delete_120_minuteON SCHEDULE EVERY 7200 SECONDSTARTS '2020-11-16 22:00:00.000'ON COMPLETION PRESERVE ENABLEDO call p_procedure_test_delete_3day_ago()

    转载地址:http://ixzbz.baihongyu.com/

    你可能感兴趣的文章
    Python基础练习之一输出10000以内的阿姆斯特朗数
    查看>>
    Python基础系列讲解—动态类型语言的特点
    查看>>
    python基础系列四:字符串,列表,字典,元组之间的转换
    查看>>
    python基础篇(9):模块
    查看>>
    python基础篇(8):异常处理
    查看>>
    python基础篇(8):字符串常用处理汇总
    查看>>
    python基础篇(7):函数进阶知识点
    查看>>
    python基础篇(6):global关键字
    查看>>
    python基础篇(5):None类型
    查看>>
    python基础篇(4):range语句
    查看>>
    python基础篇(3):print()补偿知识点
    查看>>
    python基础篇(2):字符串扩展知识点
    查看>>
    python基础篇(1):type()
    查看>>
    python基础篇(15):闭包
    查看>>
    python基础篇(14):多态
    查看>>
    python基础篇(13):类型注解
    查看>>
    python基础篇(12):继承
    查看>>
    python基础篇(11):封装
    查看>>
    python基础篇(10):自定义包
    查看>>
    python基础篇(10):类、对象与构造方法
    查看>>