在mysql中管理行到期的最佳方法

 雪_月_ 发布于 2023-02-08 14:40

应用程序执行以下操作:

将行写入具有唯一ID的表

读取表并找到唯一ID并输出其他变量(其中包括时间戳).

问题是:应用程序需要只读取未过期的行,这些行每2分钟到期一次.有几种方法可以实现这一目标:哪种方法性能最佳?

考虑读取过期的行并不重要,因为它会偶尔完成.非过期行的数量总是低于几千,但可能只有几百行.

cron作业(每分钟运行)(或MySQL事件调度)要做到这一点可根据时间戳执行下列操作之一(或任何其他的想法?):

A)添加一个BOL变量来索引表,然后读取WHERE未过期(当然基于boll变量)B)添加一个BOL变量来分区表,然后只读相关分区(我是新的分区所以我不确定这可能会有什么效果)C)读取整个表并删除已过期的每一行,然后将同一行写入另一个表D)写入时,在两个表中同时写入两行然后删除过期在一张桌子上

要么

E)根本不使用cron作业并检查每次读取的时间戳.(但为什么我会扫描整个表?过期的行对应用程序本身基本上没用)

编辑1

让我重新解释一下这个问题:

目标是仅在不到2分钟前写入行时检索行的所有列.

该表具有此结构,但可以完全重新定义

transactionID CHAR(8) NOT NULL, 
PRIMARY KEY(transactionID),
details VARCHAR(416),
tel INT(10),
time TIMESTAMP(),
address VARCHAR(60),
town VARCHAR(30),
flat VARCHAR (5),
supplier SMALLINT()

也是supplier外键

索引是transactionID并且最终是" status",一个额外的列,数据类型TO_BE_DEFINED_but_probably_SMALLINT _?()

解决方案1:使用索引列指示行的状态(已过期,活动,已使用)

通过运行cron作业将字段值从1(活动)更改为2(已过期)实现了以下操作,查询将如下所示:

$transaction = //a POST or GET 

$query = mysqli_query($con,"SELECT * FROM table WHERE transaction = '$transaction' AND status = 1");

if(mysql_num_rows($query)== 0){
   echo "Transaction expired";
}
else{
// I will show all the fields in the selected row;
}

mysqli_close($con);

解决方案2:根据每行的时间戳使用分区

运行cron作业以实现每2分钟对列进行一次分区,但查询可能更快:

$transaction = //a POST or GET 

$query = mysqli_query($con,"SELECT * FROM table WHERE transaction = '$transaction' AND PARTITION (active)");

if(mysql_num_rows($query)== 0){
   echo "Transaction expired";
}
else{
// I will show all the fields in the selected row;
}

mysqli_close($con);

然后,cron工作将与此类似

$date = date("Y-m-d H:i:s");
$time = strtotime($date);
$check = $time - (2);


$query = mysqli_query($con,"PARTITION BY RANGE (timestamp_field) 
(PARTITION active VALUES LESS THAN ($check)),
((PARTITION expired VALUES MORE THAN ($check));")

解决方案3:忘记所有这些并将时间戳大于2分钟的行复制到另一个带有cron作业的表

虽然脚本在写入方面可能很重,但是很容易实现,但是对于"已过期"表的写入效率是无关紧要的,我希望"活动"查询快速.

解决方案3B:添加行时,也将其写入另一个表,以便它只是一个cron作业必须执行的DELETE函数.

解决方案4:忘记它的所有内容和时间戳上的WHERE

$transaction = //a POST or GET 

$date = date("Y-m-d H:i:s");
$time = strtotime($date);
$check = $time - (2);

$query = mysqli_query($con,"SELECT * FROM table WHERE transaction = '$transaction' AND timestamp > $check");

if(mysql_num_rows($query)== 0){
   echo "Transaction expired";
}
else{
// I will show all the fields in the selected row;
}

mysqli_close($con);

Marjeta.. 14

您没有提到您正在使用的MySQL版本.只要你有5.1,就有事件调度程序.

CREATE EVENT clearExpired
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 MINUTES
DO
   UPDATE table SET status=0
    WHERE status <> 0
      AND TIMESTAMPDIFF(SECONDS, NOW(),table.timestamp)>120;

要么

CREATE EVENT clearExpired
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 MINUTES
DO
   DELETE FROM table
    WHERE TIMESTAMPDIFF(SECONDS, NOW(),table.timestamp)>120;

在这种情况下,您还可以设置一个触发器,在删除之前将所有已删除的行复制到历史记录表中.

为了衡量效率,创建一个表events(列:时间戳和操作),并在表中生成大量行,然后将您的事件更改为:

...
DO
   BEGIN
      INSERT INTO events SET action="clearExpired start";
      
      INSERT INTO events SET action="clearExpired end";
   END

然后你可以看到一种方式与另一种方式需要多长时间.

但是,此事件每分钟或每两分钟只运行一次,而将会有更多插入.您希望优化最常发生的操作.

1 个回答
  • 您没有提到您正在使用的MySQL版本.只要你有5.1,就有事件调度程序.

    CREATE EVENT clearExpired
    ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 MINUTES
    DO
       UPDATE table SET status=0
        WHERE status <> 0
          AND TIMESTAMPDIFF(SECONDS, NOW(),table.timestamp)>120;
    

    要么

    CREATE EVENT clearExpired
    ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 MINUTES
    DO
       DELETE FROM table
        WHERE TIMESTAMPDIFF(SECONDS, NOW(),table.timestamp)>120;
    

    在这种情况下,您还可以设置一个触发器,在删除之前将所有已删除的行复制到历史记录表中.

    为了衡量效率,创建一个表events(列:时间戳和操作),并在表中生成大量行,然后将您的事件更改为:

    ...
    DO
       BEGIN
          INSERT INTO events SET action="clearExpired start";
          <insert or delete>
          INSERT INTO events SET action="clearExpired end";
       END
    

    然后你可以看到一种方式与另一种方式需要多长时间.

    但是,此事件每分钟或每两分钟只运行一次,而将会有更多插入.您希望优化最常发生的操作.

    2023-02-08 14:43 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有