做DB查询Verus存储集合中的项目?

时间:2011-05-10 16:39:11

标签: c# performance scheduling shared-hosting quartz.net

我正在尝试制作一个提醒系统,我正在使用石英进行我的日程安排。然而,我想出了几种可行的方法,如何做我需要做的事情,但我不确定最好的方法是什么,以及如何测试它。

基本上我有一个提醒系统,用户可以设置提醒。它就像谷歌日历。您可以设置活动的日期和时间,然后通过说“提前15分钟提醒我”来设置提醒

所以你可以在2011年5月10日上午9:59举办活动,你可以说“提前15分钟”,

那将是5月10日上午10点44分。

我将在托管环境中。 (我的网站和日程安排将在相同的环境中运行,甚至在相同的解决方案中。所以它不能减慢浏览我网站的用户的速度。)

我也使用nhibernate和流畅的nhibernate来进行db查询。我在我的网站上使用asp.net mvc 3。

选项1。

每分钟进行一次数据库查询,并获取应该在该分钟发送的所有提醒。这当然意味着每分钟进行一次数据库查询,对于共享环境而言可能过于密集。

选项2。

每5分钟进行一次数据库查询并获取应该在该5分钟块中发送的所有提醒并将它们存储在一个集合中(如此内存),然后检查每一分钟需要发送的内容。

这当然会减少查询的数量,但不确定这是否会占用大量内存。

选项3

与选项2相同,但每15分钟发送一次查询并存储在集合中。

这当然意味着很少有数据库查询,但更多存储在内存中。

选项4

每15分钟进行一次数据库查询,并获取该块中的所有提醒并立即将其解除。

这意味着它们不会在内存中存储很长时间并减少查询量。但是,根据用户设置提醒的时间,电子邮件可能会提前到达,然后设置。

例如他们说在上午10:44提醒我。我的调度程序将在上午10:00开始,它将从上午10:00到上午10:15,然后上午10:15到上午10:30,然后是上午10:30到上午10:45。

因此,电子邮件实际上会提前14分钟到达。

2 个答案:

答案 0 :(得分:1)

以下是我将如何解决这个问题。

  • 在DB Tier,我会创建一个简单的队列。此消息列表还包括发送时间。查询时,此列表将在顶部显示下一个项目。

  • 消息代理将查询此列表并对顶部项目进行操作或休眠,直到列表中的顶级项目到期为止。

此技术的一个优点是,您没有代理代理在检查队列时应用业务规则。如果你想让它每分钟唤醒(例如检查是否有新的消息需要发送),那么你只需要确保这个队列每分钟都有一个事件(这个事件可能有一个不发送的类型)消息,“唤醒”消息没有目标)。代理将唤醒并执行检查。然后,如果您想应用更复杂的调度规则,它们很容易。您不必重新编写代理,只需更改队列中的消息。 (例如,当系统处于高使用状态时每10分钟检查一次,当使用率低时每20分钟检查一次,并在夜间备份期间停止检查)。这可以在不更改代理上的代码的情况下完成(和更改)。


一个简单的现实世界的例子

QueueTable
----------
ID int
deliverTime datetime
nagCount int
expireTime datetime
active bool
processed datetime (null)
' maybe some audit stuf...
' content of the message -- or external link
' etc

START:代理打这样的电话

SELECT TOP 1 * 
FROM QueueTable
WHERE active = true and processed is null
ORDER BY deliverTime DESC

然后,代理会查看deliverTime时间是什么:

  • 如果它已经过了或在下一个模糊边界(1秒?)中它发送消息然后将处理设置为db中的当前时间并循环回START:

  • 如果是将来它会睡觉直到传递时间或设置一个事件来唤醒它(取决于平台)。

我最初处理过的是一个布尔值,但是如果你使用null来等于未处理,那么它可以兼作审计字段。


无论如何每隔10分钟检查一次。

如何运作:因为结果按时间排序,最快的结果将显示在顶部。我们所做的是从现在起10分钟内添加一个项目到结果集中。因此,最高项目将不会超过当前时间10分钟。

SELECT TOP 1 * 
FROM QueueTable
WHERE active = true and processed is null
UNION ALL
SELECT NULL, DATEADD(min,GETDATE(),10), null, null, false, null, ...
ORDER BY deliverTime DESC

注意,此处的活动列用作标志,表示不会执行任何操作。此记录只是唤醒代理的标记。这种方法也可以根据其他规则进行调整(例如,因为在晚上你不需要经常检查等等。)

答案 1 :(得分:0)

如果不符合您的要求,我可能会立即抛弃选项4。

其他选项真的依赖于您的系统配置文件(有多少人在使用它?在任何给定的5/15分钟内有多少提醒?)这些是您需要回答的问题。此外,服务器上已经发生了多少活动?如果它还没有处于高压力下,那么每分钟的查询都不是很多。

最后,请记住,如果您每隔5/15分钟只进行一次查询,那么您可能会错过更改/添加/删除计划,如果它在您查询后发生并且提醒应该落在该5 / 15分钟的窗口。同样,这取决于应用程序要求是否可以接受。