Словарь / Список скорости для обновления базы данных - PullRequest
3 голосов
/ 19 августа 2011

Моя модель обновляет базу данных в соответствии с информацией, поступающей в виде словаря. То, как я сейчас это делаю, ниже:

SortedItems = db.SortedItems.ToList();
foreach (SortedItem si in SortedItems)
{
    string key = si.PK1 + si.PK2 + si.PK3 + si.PK4;
    if (updates.ContainsKey(key) && updatas[key] != si.SortRank)
    {
        si.SortRank = updates[key];
        db.SortedItems.ApplyCurrentValues(si);
    }
}
db.SaveChanges();

Было бы быстрее перебрать словарь и выполнить поиск в БД для каждого элемента? Словарь содержит только те элементы, которые были изменены, и может содержать от 2 элементов до всего набора. Моя идея для альтернативного метода будет:

foreach(KeyValuePair<string, int?> kvp in updates)
{
    SortedItem si = db.SortedItems.Single(s => (s.PK1 + s.PK2 + s.PK3 + s.PK4).Equals(kvp.Key));
    si.SortRank = kvp.Value;
    db.SortedItems.ApplyCurrentValues(si);
}
db.SaveChanges();

РЕДАКТИРОВАТЬ : Предположим, что количество обновлений обычно составляет около 5-20% от базы данных

Ответы [ 2 ]

4 голосов
/ 19 августа 2011

Давайте посмотрим:

Метод 1:

  • Вы бы перебрали все 1000 элементов в базе данных
  • Вы по-прежнему посещаете каждый элемент в Словаре и имеете 950 промахов по словарю
  • У вас все еще будет 50 обращений к базе данных.

Метод 2:

  • Вы бы повторяли каждый элемент в словаре без пропусков в словаре
  • У вас будет 50 отдельных обращений к базе данных.
  • У вас будет 50 обновлений в базе данных.

Это действительно зависит от того, насколько большой набор данных и какой% в среднем изменяется.

Вы также можете сделать что-то вроде этого:

Метод 3:

  • Сборка набора всех ключей из словаря
  • Запросите базу данных один раз для всех элементов, соответствующих этим ключам
  • Перебирать результаты и обновлять каждый элемент

Лично я бы попытался определить ваш типичный сценарий случая и профилировать каждое решение, чтобы увидеть, какое из них лучше. Я действительно думаю, что 2-е решение, тем не менее, приведет к большому количеству обращений к базе данных и сети, если у вас большой набор и большое количество обновлений, поскольку для каждого обновления ему придется дважды обращаться к базе данных (один раз для получения элемента , один раз, чтобы обновить элемент).

Так что да, это очень многословный способ сказать "это зависит ..."

Если сомневаюсь, я бы кодировал и то и другое время, основываясь на репродукциях производственных сценариев.

0 голосов
/ 19 августа 2011

Чтобы добавить к ответу @James ', вы получите самые быстрые результаты, используя сохраненный процесс (или обычную команду SQL).

Проблема с LINQ-to-Entities (и другими поставщиками LINQ, если они недавно не обновлялись) заключается в том, что они не знают, как создавать обновления SQL с помощью where предложений:

update SortedItems set SortRank = @NewRank where PK1 = @PK1 and (etc.)

Хранимая процедура будет делать это на стороне сервера, и вам потребуется только один вызов БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...