Некоторые основы
У меня есть две таблицы, одна из которых содержит пользователей, а другая - журнал с логинами.Таблица пользователей содержит примерно 15 000+ пользователей, таблица входа в систему растет и достигает 150000+ сообщений.База данных построена на SQL Server (не экспресс).
Для администрирования пользователей я получил сетку (ASPxGridView от Devexpress), которую я заполняю из ObjectDatasource.
Есть ли какие-либо общие действия ио том, чего я должен знать при суммировании количества логинов, которые сделал пользователь.
Все становится странно медленным.
Вот изображение, показывающее соответствующие таблицы.
Я пробовал несколько вещей.
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 идет медленно, но я добираюсь до цели!