应用程序执行以下操作:
将行写入具有唯一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 _?()
通过运行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);
运行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));")
虽然脚本在写入方面可能很重,但是很容易实现,但是对于"已过期"表的写入效率是无关紧要的,我希望"活动"查询快速.
$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
然后你可以看到一种方式与另一种方式需要多长时间.
但是,此事件每分钟或每两分钟只运行一次,而将会有更多插入.您希望优化最常发生的操作.
您没有提到您正在使用的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
然后你可以看到一种方式与另一种方式需要多长时间.
但是,此事件每分钟或每两分钟只运行一次,而将会有更多插入.您希望优化最常发生的操作.