У меня есть список из 80 000 элементов из веб-службы, из которых мне нужно разработать элементы для синхронизации с локальной базой данных на основе следующего:
- Вставить отсутствующие данные из веб-службы в локальную базу данных
- Обновить новые данные веб-службы, которые устарели в локальной базе данных
- Удалить из локальной базы данных, если они больше не возвращаются веб-службой).
Итерация занимает от 30 до 60 секунд, особенно в строке toInsert
. Я не думаю, что 80k - это много записей (структура TickerV2
состоит из 10 небольших полей, в основном int).
Я, должно быть, делаю что-то ужасное, какие-нибудь идеи, как сделать это более производительным, пожалуйста?
public class TickerV2
{
public string Ticker { get; set; } // Ticker is the key by which we operate
public string Name { get; set; }
public Market Market { get; set; }
public Locale Locale { get; set; }
public TickerType Type { get; set; }
public bool Active { get; set; }
public string PrimaryExch { get; set; }
public DateTime Updated { get; set; }
public CurrencyCodes Currency { get; set; }
// note the Market, Locale, CurrencyCode are all enum but not indexed
}
async Task SaveTickersToDatabaseAsync(IEnumerable<TickerV2> web)
{
using var connection = new SqlConnection(this.dbConnectionString);
await connection.OpenAsync();
var db = connection.Query<TickerV2>("SELECT * FROM Tickers").ToList();
var dbHashset = db.Select(x => x.Ticker).ToImmutableHashSet();
var webHashset = web.Select(x => x.Ticker).ToImmutableHashSet();
var toDeleteTickers = dbHashset.Except(webHashset).ToList();
var toInsertTickers = webHashset.Except(dbHashset).ToList();
var toInsert = web.Where(x => toInsertTickers.Contains(x.Ticker)).ToList();
var toUpdate = db
.Join(web, dbData => dbData.Ticker, web => web.Ticker, (db, web) => new { Db = db, Web = web })
.Where(joined => joined.Web.Updated > joined.Db.Updated)
.Select(x => x.Web)
.ToList();
}
ОБНОВЛЕНИЕ С ИСПОЛЬЗОВАНИЕМ СЛОВАРЯ
Я получил значительное увеличение скорости, используя приведенное ниже ... Я думаю, ранее мы искали Contains
(что является последовательно ??) на каждой Where
итерации - правильно ли это утверждение?
Код становится:
var toInsert = new List<TickerV2>();
var webDictionary = web.ToImmutableDictionary(x => x.Ticker);
toInsert.AddRange(from tickerKey in toInsertTickers
select webDictionary[tickerKey]);
Но не уверен, что в контексте вопроса и других операторов, если это лучший способ?