【问题标题】:Using static data in ASP.NET vs. database calls?在 ASP.NET 与数据库调用中使用静态数据?
【发布时间】:2009-06-15 00:46:19
【问题描述】:

我们正在开发一个 ASP.NET HR 应用程序,该应用程序将在每个用户会话中对相对静态的数据库表(例如税率)进行数千次调用。用户无法更改此信息,并且在公司办公室进行的更改最多每天发生一次(并且不需要立即在应用程序中刷新)。

大约 2/3 的数据库调用是针对这些静态表的,因此我正在考虑将它们移动到一组静态对象中,这些对象在应用程序初始化期间加载,然后每 24 小时刷新一次(如果应用程序在此期间没有重新启动)那时)。总内存大小约为 5MB。

我犯错了吗?这种方法有什么缺陷?

【问题讨论】:

  • 为什么每个用户会话必须进行数千次调用?
  • @tuinstoel - 用户正在输入工资支票和类似信息。单个用户可能会导入 1,000 张支票,这很容易导致对数据库的 50,000 次调用(针对每种联邦/州/地方税类型、验证步骤、最低工资评估等)。
  • 这么多电话,似乎很过分。您的 ORM 可能会阻止您以基于集合的方式而不是基于行的方式工作。
  • 完全正确 - 很可能是由其他有问题的优化技术引起的。 (注意:您想要讨论设计替代方案,但您似乎对一个明显使设计复杂化的未经检验的假设有很多支持。)如果没有更多支持信息,我遇到这种情况的第一个倾向是寻找机会重构和简化。您似乎将数据库描述为一组列表。

标签: asp.net performance


【解决方案1】:

从您提供的信息看来,您绝对应该缓存这些数据——很少更改且经常访问。但是,“静态”对象可能不合适:为什么不在缓存数据超过 N 小时时访问数据库?

您可以随意改变 N,即使您不需要特别的新鲜度——即使每天访问 DB 4 次左右也比“每个用户会话数千 [次]”要好得多!

最好在数据库信息中保留时间戳或日期时间,以记住上次更新的时间。这样,“我的缓存是否仍然新鲜”的检查通常非常轻量,只需获取“最新更新”信息并使用重建本地缓存的最新更新进行检查。有点像 HTTP“如果修改后”缓存策略,除了您将在 DB-client-side 实现大部分内容;-)。

【讨论】:

  • 这就是数据库自己做的事情。
  • 有些可以,有些不可以,有些因月相而异(或者,数据库的缓存可能会受到其他客户端的压力等),另外,如果数据库服务器远离对于 Web 服务器,数据传输无论如何都意味着延迟。本地缓存更受您的控制。
  • 您的意思是使用 ASP.NET 缓存对象而不是一组静态对象(即在单例中)?我们实际上从未将它用于数据对象缓存,并且认为存在缺点。
  • le dorfier - 我们使用的是 ORM,所以我们只需将数据拉入具有相同关系的对象数组中。代码已经处理了相关的表,所以不需要连接。
  • ORM 没有包含来自静态和动态数据的数据的对象吗?
【解决方案2】:

如果您决定缓存数据(而不是每次都调用数据库),请使用 ASP.NET 缓存而不是静态数据。 ASP.NET 缓存提供过期功能,处理多个并发请求,它甚至可以使用 SQL 2005+ 的查询通知功能自动使缓存失效。

如果你使用静态,你可能最终还是会实现这些东西。

为此使用 ASP.NET 缓存没有任何缺点。事实上,它也是为缓存数据而设计的(参见 SqlCacheDependency 类 http://msdn.microsoft.com/en-us/library/system.web.caching.sqlcachedependency.aspx)。

【讨论】:

    【解决方案3】:

    通过缓存,无论如何,dbms 对静态数据非常有效,尤其是只有 5M 的数据。

    没错,但这里的重点是完全避免数据库往返。

    ASP.NET 缓存是这项工作的正确工具。

    【讨论】:

    • 我明白这就是重点。但是这种模式的大多数应用都暗示(无论如何对我来说)将 SQL 中的连接(尤其是使用 ORM)分解为列表引用,这通常是错误的经济。正如@Mathias 指出的那样。我在这里没有看到任何关于衡量和比较设计备选方案的讨论。
    【解决方案4】:

    您没有说明如何为用户找到匹配的数据。如果它像在缓存集中查找外键一样简单,那么您不必担心。 如果您实施某种过滤/排序/分页或最差搜索,那么您可能会在某些时候错过 SQL 的查询功能。

    ORM 通常有自己的查询和 linq 使事情变得容易,但它仍然不是 SQL。 (尝试按 2 列分组)

    有时让数据库只返回结果集的键并使用缓存来填充完整集是一种好方法。

    【讨论】:

      【解决方案5】:

      思考:过早的优化。无论如何,您最终仍需要将数据作为表格处理,并且您会留下“不寻常的设计模式”。

      使用事件默认缓存,dbms 无论如何处理静态数据都非常有效,尤其是其中只有 5M 的数据。您所描述的 dbms 分区通常被描述为一种反模式。一个例子:多个客户端的多个相同数据库。关于这种模式还有其他关于 SO 的问题。我知道存在安全问题,但这样做会产生其他安全问题。我最近在一个医疗账单数据库(甚至更敏感)中看到了同样的概念,最终不得不将其重构为单个数据库。

      如果您这样做,那么我建议您至少等到您知道它正在解决一个真正的问题,然后测试以衡量它有多大的不同。这里有很多意外后果的机会。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-05
        • 2011-11-15
        • 2018-10-16
        • 1970-01-01
        • 2017-12-13
        相关资源
        最近更新 更多