0

EF ObjectContext (db-first) を使用して、多数の行 (>10,000,000) を MySQL データベースに挿入しようとしています。この質問の回答を読んだ後、 約 10,000 件の連絡先 (実際には 30,000 行、関連する他の行を含む) を挿入するために、このコード (バッチ保存) を書きました。

// 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 に増やすと (1 つのバッチが必要)、約 26 秒かかります (10,000 の連絡先の場合)。しかし、100k の連絡先 (バッチごとに 10k) を挿入しようとすると、長い時間がかかります (バッチごとに増加する時間がかかると思います)。

コンテキストが更新されているにもかかわらず、時間がかかっている理由を説明できますか? 生の SQL 以外のアイデアはありますか?

4

2 に答える 2

0

リンクした質問に対するほとんどの回答はcontext.Configuration.AutoDetectChangesEnabled = false;、あなたの例ではわかりません。だからあなたはそれを試してみるべきです。EF6 も検討することをお勧めします。この目的のためにコンテキストに AddRange メソッドがありますEntity Framework 6ベータ1で多くの行を挿入するを参照してください

于 2013-09-16T08:10:58.573 に答える