sma*_*ity 12 mysql indexing performance cron partitioning
应用程序执行以下操作:
问题是:应用程序需要只读取未过期的行,这些行每2分钟到期一次.有几种方法可以实现这一目标:哪种方法性能最佳?
考虑读取过期的行并不重要,因为它会偶尔完成.非过期行的数量总是低于几千,但可能只有几百行.
cron作业(每分钟运行)(或MySQL事件调度)要做到这一点可根据时间戳执行下列操作之一(或任何其他的想法?):
A)添加一个BOL变量来索引表,然后读取WHERE未过期(当然基于boll变量)B)添加一个BOL变量来分区表,然后只读相关分区(我是新的分区所以我不确定这可能会有什么效果)C)读取整个表并删除已过期的每一行,然后将同一行写入另一个表D)写入时,在两个表中同时写入两行然后删除过期在一张桌子上
要么
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()
Run Code Online (Sandbox Code Playgroud)
也是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);
Run Code Online (Sandbox Code Playgroud)
运行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);
Run Code Online (Sandbox Code Playgroud)
然后,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));")
Run Code Online (Sandbox Code Playgroud)
虽然脚本在写入方面可能很重,但是很容易实现,但是对于"已过期"表的写入效率是无关紧要的,我希望"活动"查询快速.
$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);
Run Code Online (Sandbox Code Playgroud)
Mar*_*eta 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;
Run Code Online (Sandbox Code Playgroud)
要么
CREATE EVENT clearExpired
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 MINUTES
DO
DELETE FROM table
WHERE TIMESTAMPDIFF(SECONDS, NOW(),table.timestamp)>120;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您还可以设置一个触发器,在删除之前将所有已删除的行复制到历史记录表中.
为了衡量效率,创建一个表events(列:时间戳和操作),并在表中生成大量行,然后将您的事件更改为:
...
DO
BEGIN
INSERT INTO events SET action="clearExpired start";
<insert or delete>
INSERT INTO events SET action="clearExpired end";
END
Run Code Online (Sandbox Code Playgroud)
然后你可以看到一种方式与另一种方式需要多长时间.
但是,此事件每分钟或每两分钟只运行一次,而将会有更多插入.您希望优化最常发生的操作.
| 归档时间: |
|
| 查看次数: |
11577 次 |
| 最近记录: |