优化查询以检索分布在不同服务器上的不同数据库中的数据以发送邮件

时间:2013-10-30 04:45:11

标签: c# asp.net sql-server-2008

我正在开发一个使用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 个答案:

答案 0 :(得分:2)

我假设您需要不到1分钟,因为您希望每分钟都执行此操作,因此在发送电子邮件之前只有短暂的延迟。

理想情况下,您需要以相反的方式执行此操作。将NotifyQueue表放在中心位置,然后让600个不同的客户端将记录写入该表。 (或者将DB的数据插入触发器中的中心位置)然后,您可以在单个表上运行该服务,并通过一个非常快速的调用和循环处理所有记录。这应该可以让你在1分钟内完成。

否则,为您的服务添加配置,以允许您指定一组数据库,然后运行它的多个副本,每个副本只处理一个小的数据库子集,以便每个花费的时间少于1分钟