【问题标题】:Hierarchy in SQL and ASP.netSQL 和 ASP.net 中的层次结构
【发布时间】:2012-08-30 02:36:17
【问题描述】:

我正在创建一个包含PostsComments 的网页。但是,当我在渲染该Post 期间为每个Post 检索Comments 时,检索速度非常慢。我的猜测是,这是由于频繁打开/关闭连接。无论如何,它不能很好地扩展。

为了解决这个问题,我正在考虑将两个实体合并为一个,并以多态方式对 PostsComments 进行建模。换句话说,Entry 成为一个超类,由PostComment 子类。

任何人都可以就这是否是一种有效的方法给我一些建议吗?或者,我愿意接受其他建议,这些建议也可能解决我可能没有想到的嵌套 Repeater/DataList 性能问题。

【问题讨论】:

  • 如果我的回答对您有所帮助,请考虑通过单击其分数下方的小复选框将其标记为“已接受”。如果没有,请让我知道您需要什么进一步的信息,以便我为您提供更多帮助。

标签: asp.net sql sql-server ado.net hierarchical-data


【解决方案1】:

即使您的博客帖子中有数千个 cmets,它仍然可以正常工作。
RDBMS 表通常包含数百万条记录。

频繁打开和关闭连接将成为性能瓶颈。
您应该一次获取所有数据,然后将其传递给嵌套中继器。

【讨论】:

    【解决方案2】:

    扩展 nunespascal 所说的内容:

    无论您是通过两个单独的表将数据作为两个单独的实体拉回,还是从同一个表中以多态方式将其拉回,听起来您遇到的问题是如何 您正在请求数据。

    在 C#-ish EF 伪代码中考虑这两种方法:

    方法 1:迭代加载子节点

    var posts = db.Posts;
    foreach (Post p in posts) {
        Html.Render(p);
    
        var comments = db.Comments.Where(c => c.PostId == p.PostId);
        foreach (Comment c in comments) {
            Html.Render(c);
        }
    }
    

    这听起来就像您在当前的中继器迭代中所做的那样。对于您访问的每个帖子,加载属于它的 cmets - 并将它们渲染出来。

    这正是您所描述的瓶颈,您正在打开/关闭大量连接并运行大量单独的原子 SQL 语句。如果可以,请避免这种情况。

    方法 2:一起加载父母/孩子

    var posts = db.Posts.Top(10);
    // ^ The .Top(10) limits the result-set to a manageable number of posts (10).
    
    var ids = posts.Select(p => p.PostId);
    // ^ This line creates an Enumerable list of the IDs of your loaded posts.
    
    var comments = db.Comments.Where(c => ids.Contains(c.PostId));
    // ^ This line loads all the comments which belong to the 10 posts you loaded.
    
    foreach (Post p in posts) {
        Html.Render(p);
    
        foreach (Comment c in comments.Where(c => c.PostId == p.PostId)) {
            // This loop iterates the comments in the same way the previous example
            // showed, with the exception that it iterates *in memory*, rather than
            // running additional SQL on each iteration.
            Html.Render(c);
        }
    }
    

    因为您在第二个示例中加载了内存中的所有项目,所以您保存了所有往返行程 - 只创建了 2 个 SQL 语句,这两个语句都在开始时运行。

    如果您实际使用的是 EF4/5(上面的代码基于此),您实际上甚至可以执行以下操作:

    var posts = db.Posts.Include("Comments");
    // ^ This line loads both Posts and Comments in a single SQL statement
    
    foreach (Post p in posts) {
        Html.Render(p);
    
        foreach (Comment c in p.Comments) {
            // EF5 and other ORMs can create a .Comments property which contains an
            // Enumerable list of the comments, already filtered on the FK binding
            Html.Render(c);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-10
      • 1970-01-01
      • 2011-08-27
      • 2020-11-30
      • 2017-02-04
      相关资源
      最近更新 更多