Прежде всего, в любое время, когда вы говорите: «Итерация по строкам из базы данных», вам лучше говорить о какой-то очень сложной операции, выполняемой для каждой строки. В противном случае вы можете и должны думать в наборах!
Похоже, вы берете все в почтовую очередь и сбрасываете таблицу после отправки всех писем. Теперь я должен отметить, что ваш limit 0,1
немного сбивает с толку, так как у вас нет order by
. Ни одна база данных не хранит вещи в надежном порядке (и на то есть веские причины - она должна постоянно перемещать вещи для их оптимизации) Итак, лучший код будет:
// get next mail in queue
$st = $db->prepare('
SELECT id, to, subject, message, attachment
FROM shop_mailqueue
ORDER BY id ASC
LIMIT 0, ' . $limit);
$st->execute();
$lastid = 0;
while ($mail = $st->fetch(PDO::FETCH_ASSOC))
{
// send queued mail
$mailer = new PHPMailer();
$mailer->AddAddress($mail['to']);
$mailer->SetFrom('info@xxx.nl', 'xxx.nl');
$mailer->Subject = $mail['subject'];
$mailer->Body = $mail['message'];
$mailer->AddAttachment($mail['attachment']);
$mailer->Send();
$lastid = $mail['id'];
}
// remove mail from queue
$st = $db->prepare('DELETE FROM shop_mailqueue WHERE id <= ' . $lastid);
$st->execute();
Таким образом, вы делаете только два (считайте их!) Запроса к базе данных, что на намного более оптимально, чем каждый раз возвращать одну строку назад.
Теперь, если вся сделка $limit
не нужна, и вы действительно хотите откатить все строки в очереди, а затем просто вывести ее из очереди, измените свой оператор delete
на:
TRUNCATE TABLE shop_mailqueue
Видите, truncate
не связан логикой транзакции, а просто стирает таблицу, не задавая вопросов. Поэтому это очень быстро (как в миллисекундах, независимо от размера таблицы). delete
просто не имеет такой скорости. Просто помните, что truncate
- это ядерный вариант - как только вы truncate
, он исчезнет.