将数以百万计的邮件插入MySQL表“EmailQueue”中,其中包含以下字段,
通常,行将以“待定”状态插入,但会在状态列中插入一些优先级高的邮件,例如忘记/重置密码。
cron作业将每小时运行一次,并在每个循环中将批量的20000封邮件作为循环发送,直到完成发送所有电子邮件。现在我想首先发送优先邮件,即使cron作业正在运行,也可以将其添加到电子邮件队列中。
实现这一目标的最佳方法是什么?我不确定stackoverflow是否是提出这个问题的地方,但不确定更好的地方。感谢您提前提供任何帮助。
答案 0 :(得分:1)
如果我们忽略"在cron运行时添加"一秒钟,这将选择' Prioritized'第一:
ORDER BY FIELD(status, "Prioritized"), id ASC
这将对所有行进行排序,其中status = Prioritized然后按ID排序。 More info/examples here
在 cron运行时添加更加困难,这成为一个逻辑挑战。如果您执行SELECT * FROM emails ORDER BY FIELD(status, "Prioritized"), id ASC
,则在选择时选择数据中的数据。如果在您运行查询后添加了项目,则它不会出现在返回的数据集中。
为了得到你想要的东西,你需要将你的代码分成更小的选择:
$continueProcesss = false;
$current = 0;
$itemsPerBatch = 25;
while( $continueProcesss ){
$query = "SELECT * FROM emails ORDER BY FIELD(status, 'Prioritized'), id ASC`
LIMIT $current,$itemsPerBatch";
$result = yourQueryMethod($query);
if( $result->num_rows===0 ){
$continueProcesss = false;
break;
} else{
$current += $itemsPerBatch; // next round, we skip another $itemsPerBatch rows
}
}
答案 1 :(得分:0)
这是使用正确查询的问题,例如,如果您知道作业将在每个电子邮件中运行,直到队列耗尽:
SELECT *
FROM EmailQueue
WHERE status IN ('Pending','Prioritized')
ORDER BY status DESC, created_datetime ASC
LIMIT 0,100;
结果是,每次运行查询时,首先会获得优先级的电子邮件,然后是最早的电子邮件,这些电子邮件都是由最早的电子邮件排序的。
您可以多次运行此批次,直到队列耗尽或每小时最多200次以匹配20,000小时限制。
我假设您在开始处理时将状态更改为Processing
,完成后您将状态更改为Processed
。这就是为什么你总是从0开始而不是增量数字。