我正在尝试使用 EF ObjectContext(db-first)将大量行(>10,000,000)插入 MySQL 数据库。在阅读了这个问题的答案后, 我编写了这段代码(批量保存)来插入大约 10,000 个联系人(实际上是 30k 行;包括相关的其他行):
// 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(10k 个联系人)的日志。注意随着批次#增加所需的时间增加:
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 秒(对于 10k 联系人)。但是当我尝试插入 10 万个联系人(每批 1 万个)时,需要很长时间(我猜每批的时间会增加)。
你能解释一下为什么尽管上下文被更新了,但它却花费了越来越多的时间吗?除了原始 SQL,还有其他想法吗?