应用程序执行以下操作:
问题是:应用程序需要只读取未过期的行,这些行每2分钟到期一次。有几种方法可以实现这一目标:哪种方法性能最佳?
考虑读取过期的行并不重要,因为它会偶尔完成。非过期行的数量总是低于几千,但可能只有几百行。
基于时间戳,cron作业(每分钟运行)(或mysql事件计划)可以是以下之一(或任何其他想法?):
A)添加一个BOL变量来索引表,然后读取WHERE未过期(当然基于boll变量) B)添加一个BOL变量来对表进行分区,然后只读取相关的分区(我是分区的新手,所以我不知道这可能会如何解决) C)读取整个表并删除已过期的每一行,然后将同一行写入另一个表 D)写入时,在两个表中同时写两行,然后在一个表中删除过期的行
OR
E)根本不使用cron作业并检查每次读取的时间戳。 (但为什么我会扫描整个表?过期的行对应用程序本身来说基本无用)
让我重新解释一下这个问题:
目标是仅在少于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);
答案 0 :(得分: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 or delete>
INSERT INTO events SET action="clearExpired end";
END
然后你可以看到一种方式与另一种方式需要多长时间。
但是,此事件每分钟或每两分钟只运行一次,而且会有更多插入。您希望优化最常发生的操作。