【问题标题】:mysql querying in batchesmysql批量查询
【发布时间】:2019-06-14 13:48:53
【问题描述】:

我在一个表中有超过 100 万行,我必须在 cron 作业中根据该查询进行查询并向用户发送电子邮件。我有这样的代码:

$start = 0;
$limit = 1000;
while ( true) {
    $query_results = db_result("SELECT * FROM table LIMIT $start, $limit");

    if (count($query_result) == 0) {
        break;
    }

    foreach ( $query_result as $result) {
        $email = $result ['email'];

        send_email($email);
    }

    $start += $limit;
}

有没有更好更有效的方法来批量查询数百万行?如果脚本崩溃以避免向人们发送重复的电子邮件?如果脚本崩溃并再次重新运行,它将向剩余的人发送电子邮件,而无需我在上面的代码中进行数据库查找以检查每个人是否收到电子邮件?

每天都会发送电子邮件。根据每个人是否满足某些要求,它可能每天都会发送给同一个人。

【问题讨论】:

  • 我很想似是而非地否决这个问题......我认为我的电子邮件地址是此类例程已经针对的数百万个电子邮件地址之一,我不希望发送电子邮件的例程更高效.
  • 这就是为什么我要确保我不会重复发送!

标签: php mysql sql


【解决方案1】:

您需要在数据库中存储一些状态。

您需要一个表格,其中包含批处理(邮寄)ID 和主表格中电子邮件 ID 的列。

然后你 INSERT 在该表中为发送的每封电子邮件添加一行,你可以将 SELECT 替换为:

SELECT * FROM table WHERE id NOT IN (SELECT id FROM email_sent WHERE batch=?) LIMIT ?

或者,您可以添加一列来说明电子邮件是否已发送(或发送时间)。然后您首先将此批次的所有电子邮件添加到表中:

INSERT INTO batch_email (batch_id, email_id) SELECT ?,email.id FROM email WHERE ...

然后您从那里选择要发送到的电子邮件:

SELECT * FROM table JOIN batch_email ON table.id=batch_email.id WHERE NOT sent LIMIT ?

最后,您在发送电子邮件后设置sent

UPDATE batch_email SET sent=true WHERE id=?

【讨论】:

    【解决方案2】:

    如果你在内存中获取所有数据,你可以不存储在 mysql 中。假设您的 id 已编入索引,因此您获取所有 ids 值并将其保存在数组中,并使用您的 php 代码执行

    喜欢这个

      select * from table A where id >1000 limit 1000
    

    然后在这个循环结束时将 1000 的值增加到 2000,这样直到你到达终点。使用这种方法,您无需在每次通过后更新数据库

    【讨论】:

      猜你喜欢
      • 2010-10-14
      • 2012-01-04
      • 2012-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-27
      • 1970-01-01
      相关资源
      最近更新 更多