Спасибо всем за ценные комментарии!
Чтобы оставить вышеупомянутые вопросы-комментарии в строках, я создаю ответ здесь.
Я протестировал в комментариях предоставленные рекомендации с 27 000 записей в контакте таблицы и 47 000 записей в таблице zip_city, но без изменения индекса базы данных (добавьте индекс, предложенный Panagiotis Kanavos).
Ниже приведены результаты теста производительности
Исходный код 1, требуется 113 секунд .
var ctx = new DbContext();
var qry = ctx.contact.Join(ctx.zip_city, c => new { c.zip, c.city }, z => new { z.zip, z.city }, (c, z) => new { c, z })
.Select(x => new dtoContact { id = x.c.id }).ToList();
foreach (var con in ctx.contact)
{
if (qry.Any(x => x.Id == con.id))
{
con.status = "P/O";
}
else
{
con.status = "???";
}
}
ctx.SaveChanges();
Основываясь на DevilSuichiro, «массовые сохранения» недоступны в DbContext с MySQL, поэтому здесь только SaveChanges() вызывается для отдельных партий из 100 объектов.Это займет 107 секунд .
var ctx = new DbContext();
var qry = ctx.contact.Join(ctx.zip_city, c => new { c.zip, c.city }, z => new { z.zip, z.city }, (c, z) => new { c, z })
.Select(x => new dtoContact { id = x.c.id }).ToList();
int count = 0;
foreach (var con in ctx.contact)
{
if (qry.Any(x => x.Id == con.id))
{
con.status = "P/O";
}
else
{
con.status = "???";
}
++count;
if (count % 100 == 0)
{
ctx.SaveChanges();
}
}
ctx.SaveChanges();
На основе рандом-рандома, HashSet используется для повышения производительности.Это по-прежнему занимает более 100 секунд .
var ctx = new DbContext();
var qry = ctx.contact.Join(ctx.zip_city, c => new { c.zip, c.city }, z => new { z.zip, z.city }, (c, z) => new { c, z }).Select(id = x.c.id);
var ids = new HashSet<int>(qry);
foreach (var con in ctx.contact)
{
if (ids.Contains(con.id))
{
con.status = "P/O";
}
else
{
con.status = "???";
}
}
ctx.SaveChanges();
Исходный код 2, требуется 67 секунд .
var ctx = new DbContext();
var zc = ctx.zip_city.ToList();
foreach (var con in ctx.contact)
{
if (zc.Any(x => x.zip == con.zip && x.city == con.city))
{
con.status = "P/O";
}
else
{
con.status = "???";
}
}
ctx.SaveChanges();
По материалам PanagiotisKanavos, использование любых ORM (как здесь DbContext SaveChanges ()) для этого Data-UPDATE действительно не подходит.
Я тестировал код от alex, nvoigt, это занимает менее 2 секунд .
var ctx = new DbContext();
string sql = "update contact set status = '???'; " +
"update contact c inner join zip_city z on c.plz = z.plz and c.ort = z.ort set c.status = 'P/O'; ";
ctx.Database.ExecuteSqlCommand(sql);