优化查询以从分布在不同服务器上的不同数据库中检索数据以发送邮件
本文关键字:数据 检索 数据库 查询 分布 优化 服务器 | 更新日期: 2023-09-27 18:37:20
我正在开发一个使用Admin
数据库的应用程序,其中包含所有客户端及其数据库的详细信息(以及服务器的名称),它们都用于连接此应用程序。所有客户机数据库都包含一个名为 NotifyQueue
的表。此表包含要在预设时间发送的所有排队邮件(预设是指每个客户端设置的时间间隔)。
我们的前端应用程序编写了一个服务,该服务会触发从所有这些NotifyQueue
表为所有客户端发送邮件。问题是我们目前有超过 600 个数据库分布在不同的服务器上,我们需要提取这 1000 多封NotifyQueue
邮件并发送它们。这需要相当长的时间,有时大约需要 15 - 20 分钟。我们需要的是每 1 分钟发送一次大量邮件。目前使用的逻辑是遍历每个数据库并检索排队的邮件,然后再次遍历每封邮件以发送它。代码如下
private void SendEMail(List<EmailNotifyQueue> listNotifyQueue, SqlConnection objConn, string Module, EmailSettings emailSettings)
{
try
{
for (int i = 0; i < listNotifyQueue.Count; i++)
{
ClientConfig cfg = ClientConfig.CurrentSetings;
objemailinfo = new EmailInformation();
objemailinfo.DatabaseName = emailSettings.DatabaseName;
objemailinfo.DatabaseServer = emailSettings.DatabaseServer;
objemailinfo.SmtpServer = cfg.SMTPServer;
objemailinfo.RequireAuthentication = emailSettings.EmailRequiresAuthentication;
objemailinfo.SmtpUserName = emailSettings.EmailUserName;
objemailinfo.SmtpPassWord = emailSettings.EmailPassword;
objemailinfo.EnableNotifications = emailSettings.EnableNotifications;
if (lstNotifyQueue[i].ToAddress != string.Empty)
{
objemailinfo.To = ExcludeMail(lstNotifyQueue[i].ToAddress.Replace(';', ','), emailSettings.EmailExclusions, emailSettings.DatabaseName);
objemailinfo.Body = lstNotifyQueue[i].Body;
if (Module == "IM")
objemailinfo.From = lstNotifyQueue[i].FromAddress;
else
objemailinfo.From = emailSettings.EmailAddress;
if (objemailinfo.From != string.Empty)
{
objemailinfo.Subject = lstNotifyQueue[i].Subject;
if (objemailinfo.To != string.Empty)
if (objemailinfo.sendEmail())
{
ChangeEmailNotifyQueue(Convert.ToInt32(lstNotifyQueue[i].Key), objConn, emailSettings.DatabaseName, Module);
if (!String.Equals(Module, "IM"))
{
try
{
LogEmailNotificationInModules(lstNotifyQueue[i], objConn);
}
catch (Exception ex)
{
//Let the exception not break the email sending logic so simply log the exception
SchedulerHelper.LogEmailNotification(SchedulerHelper.FormatException(emailSettings.DatabaseName, "Scheduler", "SendEMail",
"Exception occured while Logging EmailNotification Status" + ex.Message));
}
}
}
}
}
}
}
catch (Exception ex)
{
SchedulerHelper.LogEmailNotification(SchedulerHelper.FormatException(emailSettings.DatabaseName, "Scheduler", "SendEMail", ex.Message));
}
}
每个数据库都调用此方法,这意味着,目前这将调用 600 次
任何人都可以帮助我找到更好的解决方案来快速检索所有数据并在 1 分钟内发送?
更新我们计划使用线程同时运行,但逻辑令人困惑
我假设您需要在 1 分钟内执行此操作,因为您希望它每分钟执行一次,以便在发送电子邮件之前只有短暂的延迟。
理想情况下,您需要以相反的方式执行此操作。将 NotifyQueue 表放在一个中心位置,然后让 600 个不同的客户端将记录写入该表。(或让数据库将数据插入到触发器的中心位置)然后,您可以在单个表上运行该服务,并通过一个非常快速的调用和循环来处理所有记录。这应该让你在 1 分钟内。
否则,将配置添加到服务,以允许您指定一组数据库,然后运行它的多个副本,每个副本仅处理一小部分数据库,以便每个数据库花费的时间少于 1 分钟。