简体   繁体   English

实体框架添加更多行会降低性能

[英]Entity Framework Add Performance Degrades With More Rows

I'll begin this post by noting that I'm entirely new to the .NET world. 在开始这篇文章之前,请注意我是.NET世界的新手。 ASP, EntityFramework, Linq, etc. are all mostly unknown magic at this point. 此时,ASP,EntityFramework,Linq等几乎都是未知的魔术。

Having said that, I've built myself a neat Web API chat-like application with SignalR support for real-time events. 话虽如此,我已经为自己构建了一个简洁的Web API聊天类应用程序,并具有对实时事件的SignalR支持。 It works quite well, but I'm having some performance problems with the Add function. 它工作得很好,但是Add函数存在一些性能问题。

In my chat application, there are "Pads" (chat rooms) which contain a number of "Mates" and "Messages". 在我的聊天应用程序中,有“ Pad”(聊天室),其中包含许多“ Mate”和“ Messages”。 Here's my Pad model for reference: 这是我的Pad模型供参考:

public class Pad
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid PadId { get; set; }
    public string StreetAddress { get; set; }
    public int ZipCode { get; set; }
    public virtual ICollection<Mate> Mates { get; set; }
    public virtual ICollection<Message> Messages { get; set; }
}

My problem lies in my SignalR hub that processes a new Message sent to a particular pad. 我的问题出在SignalR集线器上,该集线器处理发送到特定键盘的新消息。 These two lines take about half a second to process. 这两条线大约需要半秒的时间来处理。

pad.Messages.Add(msg); // pad is the Pad entity already fetched from the db context
db.Messages.Add(msg);

But they only take that long when Pad.Messages contains a large number of messages. 但是,只有在Pad.Messages包含大量消息时,它们才会花费那么长时间。 Thousands. If I am sending to a pad with few to no messages, it executes almost instantly. 如果我要发送的邮件很少或根本没有邮件,它将几乎立即执行。

My initial 'trick' to improve the perceived performance here is to move the adding functions to after I send the notification back to the clients, but I realize something like this could present a potential problem later when there are tens or hundreds of thousands of messages in one pad. 我最初在此处提高感知性能的“技巧”是在将通知发送回客户端之后将添加功能移至其中,但是我意识到,当成千上万条消息以后,类似的事情可能会带来潜在的问题在一个垫子上。

Any advice here would be greatly appreciated! 这里的任何建议将不胜感激!

Here is the entire message send method for reference: 这是整个消息发送方法供参考:

public void SendMessage(string pad_id, string body)
{
    var user_id = IdentityExtensions.GetUserId(Context.User.Identity);
    body = body.Trim();
    if (body.Length <= 0)
    {
        return;
    }
    // Check that the user belongs in this pad...
    var user = (from u in db.Users
                where u.Id == user_id
                select u).First();
    var pad = (from p in user.Pads where p.PadId == new Guid(pad_id) select p).FirstOrDefault();
    if (pad != null) {
        // Save the message to the database
        var msg = new Message()
        {
            MessageId = new Guid(),
            Author = user,
            Body = body,
            SendTime = DateTimeOffset.UtcNow,
            Pad = pad
        };

        pad.Messages.Add(msg); // These two lines
        db.Messages.Add(msg); // Are the culprit.
        db.SaveChangesAsync();
        Clients.Group(pad_id).messageReceived(user.Id, pad_id, body, DateTimeOffset.UtcNow); // Send message to clients
    }
}

EDIT : I'm on EF 6.0.0 编辑 :我在EF 6.0.0

From your code, all you want to do is add 1 row (Message) to the table. 从您的代码中,您要做的就是在表中添加1行(消息)。

While constructing the Message entity, just use the padid instead of the Pad object. 在构造Message实体时,只需使用padid而不是Pad对象即可。 That way you don't need to deal with all the pad objects. 这样,您无需处理所有的填充对象。 From a DB perspective, you just need to add a Message row with a PadId key. 从数据库角度来看,您只需要添加带有PadId键的Message行。

    var msg = new Message()
    {
        MessageId = new Guid(),
        Author = user,
        Body = body,
        SendTime = DateTimeOffset.UtcNow,
        PadId = new Guid(pad_id)
    };

    // pad.Messages.Add(msg); // don't need this.
    db.Messages.Add(msg);

The above should always insert one row and not depend on the number of messages in the pad. 上面的内容应始终插入一行,而不取决于填充板中的消息数量。 If it still gives a performance problem, then adding a single row is causing a lot of index updates to your table. 如果仍然存在性能问题,则添加一行会导致表的索引更新很多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM