一些基础知识
我有两张表,一张保存用户,一张保存登录日志。用户表包含大约 15000 多个用户,登录表正在增长并达到 150000 多个帖子。该数据库建立在 SQL Server(不是 express)之上。
为了管理用户,我得到了一个从 ObjectDatasource 填充的 gridview(来自 Devexpress 的 ASPxGridView)。
在总结用户的登录次数时,我应该知道哪些一般的注意事项。
事情变得异常缓慢。
这是一张显示相关表格的图片。
我已经尝试了几件事。
DbDataContext db = new DbDataContext();
// Using foregin key relationship
foreach (var proUser in db.tblPROUsers)
{
var count = proUser.tblPROUserLogins.Count;
//...
}
执行时间:01:29.316(1分29秒)
// By storing a list in a local variable (I removed the FK relation)
var userLogins = db.tblPROUserLogins.ToList();
foreach (var proUser in db.tblPROUsers)
{
var count = userLogins.Where(x => x.UserId.Equals(proUser.UserId)).Count();
//...
}
执行时间:01:18.410(1分18秒)
// By storing a dictionary in a local variable (I removed the FK relation)
var userLogins = db.tblPROUserLogins.ToDictionary(x => x.UserLoginId, x => x.UserId);
foreach (var proUser in db.tblPROUsers)
{
var count = userLogins.Where(x => x.Value.Equals(proUser.UserId)).Count();
//...
}
执行时间:01:15.821(1分15秒)
提供最佳性能的模型实际上是字典。但是,您知道我想听到的任何选项,以及在处理如此大量的数据时这种编码是否存在“不好”的地方。
谢谢
==================================================== ======
根据 BrokenGlass 示例更新了模型
// By storing a dictionary in a local variable (I removed the FK relation)
foreach (var proUser in db.tblPROUsers)
{
var userId = proUser.UserId;
var count = db.tblPROUserLogins.Count(x => x.UserId.Equals(userId));
//...
}
执行时间:02:01.135(2分1秒)
除此之外,我创建了一个存储一个简单类的列表
public class LoginCount
{
public int UserId { get; set; }
public int Count { get; set; }
}
并在总结方法中
var loginCount = new List<LoginCount>();
// This foreach loop takes approx 30 secs
foreach (var login in db.tblPROUserLogins)
{
var userId = login.UserId;
// Check if available
var existing = loginCount.Where(x => x.UserId.Equals(userId)).FirstOrDefault();
if (existing != null)
existing.Count++;
else
loginCount.Add(new LoginCount{UserId = userId, Count = 1});
}
// Calling it
foreach (var proUser in tblProUser)
{
var user = proUser;
var userId = user.UserId;
// Count logins
var count = 0;
var loginCounter = loginCount.Where(x => x.UserId.Equals(userId)).FirstOrDefault();
if(loginCounter != null)
count = loginCounter.Count;
//...
}
执行时间:00:36.841(36秒)
到目前为止的结论,用 linq 总结很慢,但我到了那里!