我正在尝试使用EF ObjectContext(db-first)将大量行(> 10,000,000)插入MySQL数据库。阅读此问题的答案后,我编写了以下代码(批量保存),以插入约10,000个联系人(实际上为3万行;包括其他相关行):
// var myContactGroupId = ...;
const int maxContactToAddInOneBatch = 100;
var numberOfContactsAdded = 0;
// IEnumerable<ContactDTO> contacts = ...
foreach (var contact in contacts)
{
var newContact = AddSingleContact(contact); // method excerpt below
if (newContact == null)
{
return;
}
if (++numberOfContactsAdded % maxContactToAddInOneBatch == 0)
{
LogAction(Action.ContactCreated, "Batch #" + numberOfContactsAdded / maxContactToAddInOneBatch);
_context.SaveChanges();
_context.Dispose();
// _context = new ...
}
}
// ...
private Contact AddSingleContact(ContactDTO contact)
{
Validate(contact); // Simple input validations
// ...
// ...
var newContact = Contact.New(contact); // Creates a Contact entity
// Add cell numbers
foreach (var cellNumber in contact.CellNumbers)
{
var existingContactCell = _context.ContactCells.FirstOrDefault(c => c.CellNo == cellNumber);
if (existingContactCell != null)
{
// Set some error message and return
return;
}
newContact.ContactCells.Add(new ContactCell
{
CellNo = cellNumber,
});
}
_context.Contacts.Add(newContact);
_context.ContactsInGroups.Add(new ContactsInGroup
{
Contact = newContact,
// GroupId = some group id
});
return newContact;
}
但是似乎添加的触点越多(分批),则花费的时间就越多(非线性)。这是批量大小为100(10,000个联系)的日志。请注意,随着批号的增加,所需的时间也随之增加:
12:16:48 Batch #1
12:16:49 Batch #2
12:16:49 Batch #3
12:16:50 Batch #4
12:16:50 Batch #5
12:16:50 Batch #6
12:16:51 Batch #7
12:16:52 Batch #8
12:16:53 Batch #9
12:16:54 Batch #10
...
...
12:21:26 Batch #89
12:21:32 Batch #90
12:21:38 Batch #91
12:21:44 Batch #92
12:21:50 Batch #93
12:21:57 Batch #94
12:22:03 Batch #95
12:22:10 Batch #96
12:22:16 Batch #97
12:22:23 Batch #98
12:22:29 Batch #99
12:22:36 Batch #100
花了6分钟48秒。如果我将批次大小增加到10,000(需要一个批次),则大约需要26秒(对于1万个联系人)。但是,当我尝试插入100k联系人(每批次10k)时,会花费很长的时间(我想这会增加每批次的时间)。
您能解释一下为什么尽管上下文已更新但要花费越来越多的时间吗?除了原始SQL,还有其他想法吗?
终于明白了。看来方法Validate()
是罪魁祸首。它具有一个存在检查查询,以检查联系人是否已经存在。因此,随着联系人的添加,数据库增加,并且随着批号的增加,需要更多的时间进行检查。主要是因为未索引(正在比较的)单元格编号字段。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句