zoukankan      html  css  js  c++  java
  • [转]How to Improve Entity Framework Add Performance?

    本文转自:http://entityframework.net/improve-ef-add-performance

    When you overuse the Add() method for multiple entities, your application suffers from performance issues.

     
     
     
     
     
    1
    using (var ctx = new CustomerContext())
    2
    {
    3
        foreach(var line in lines)
    4
        {
    5
            var customer = new Customer();
    6
            // ...code...
    7
            ctx.Customers.Add(customer);
    8
        }
    9
    
    
    10
        ctx.SaveChanges();
    11
    }
     
     

    Answer

    Is Entity Framework Add Really Slow?

    In fact, the Add method is not slow at all. Adding an entity to a list cannot be that slow. It's the DetectChanges method invoked inside the Add method which is insanely slow!

    Using the Add method in a loop is usually a poor practice which impacts your application performance severely when poorly used.

    • USE AddRange over Add (Recommended)
    • SET AutoDetectChanges to false
    • SPLIT SaveChanges in multiple batches

    When adding multiple entities, you should always use Entity Framework AddRange once with a list instead of calling multiple time the Add method.

    Why?

    • The Add method DetectChanges after every records added.
    • The AddRange method DetectChanges after all records are added.

    Performance Comparisons

    Operations100 Entities1,000 Entities10,000 Entities
    Add 15 ms 1,050 ms 105,000 ms
    AddRange 1 ms 10 ms 120 ms

    Note:

    • *: SaveChanges time not included
    • **: Entity with two relations

    How?

    1. CREATE a list
    2. ADD entity to the list
    3. USE AddRange with the list
    4. SaveChanges
    5. Done!
     
     
     
     
     
    1
    using (var context = new EntityContext())
    2
    {
    3
        // 1. CREATE a list
    4
        List<Customer>  list = new List<Customer>();
    5
    
    
    6
        for(int i = 0; i < 2000; i++)
    7
        {
    8
            var customer = new Customer();
    9
            // ...code...
    10
    
    
    11
            // 2. ADD entity to the list
    12
            list.Add(customer);
    13
        }
    14
    
    
    15
        // 3. USE AddRange with the list
    16
        context.Customers.AddRange(list);
    17
    
    
    18
        // 4. SaveChanges
    19
        ctx.SaveChanges();
    20
    
    
    21
        // 5. Done!
    22
    }
     
     

    Try it online

    SET AutoDetectChanges to false

    When adding multiple entities, if you cannot use AddRange, set Entity Framework AutoDetectChanges to false

    Why?

    • The Add method DetectChanges after every records added.

    By disabling AutoDetectChanges, the DetectChanges method will only be invoked when you do it.

    Performance Comparisons

    Operations100 Entities1,000 Entities10,000 Entities
    True (Default) 15 ms 1,050 ms 105,000 ms
    False 1 ms 14 ms 180 ms

    Note:

    • *: SaveChanges time not included
    • **: Entity with two relations

    How?

    1. SET AutoDetectChangesEnabled = false
    2. CALL DetectChanges before SaveChanges
    3. SaveChanges
    4. Done!
     
     
     
     
     
    1
    using (var context = new EntityContext())
    2
    {
    3
        // 1. SET AutoDetectChangesEnabled = false
    4
        context.Configuration.AutoDetectChangesEnabled = false;
    5
    
    
    6
        List<Customer>  list = new List<Customer>();
    7
    8
        for(int i = 0; i < 2000; i++)
    9
        {
    10
            var customer = new Customer();
    11
            // ...code...
    12
    
    
    13
            list.Add(customer);
    14
        }
    15
    
    
    16
        context.Customers.AddRange(list);
    17
    
    
    18
        // 2. CALL DetectChanges before SaveChanges
    19
        context.ChangeTracker.DetectChanges();
    20
    
    
    21
        // 3. SaveChanges
    22
        context.SaveChanges();
    23
    
    
    24
        // 4. Done!
    25
    }
     
     

    Try it online

    SPLIT SaveChanges into multiple batches

    This solution is not recommended. When adding multiple entities, split entities with a batch size in multiple different contexts.

    Why?

    More tracking entities your context contains, slower the DetectChanges method is! So by reducing the number of entities by context, you improve the performance.

    Performance Comparisons

    Operations100 Entities1,000 Entities10,000 Entities
    Unlimited 15 ms 1,050 ms 105,000 ms
    10 3 ms 40 ms 350 ms
    100 15 ms 125 ms 1,200 ms
    1,000 15 ms 1,050 ms 10,200 ms

    Note:

    • *: SaveChanges time not included
    • **: Entity with two relations

    How

    1. CREATE a batchSize variable
    2. CALL SaveChanges before creating a new batch
    3. CALL SaveChanges
    4. Done!
     
     
     
     
     
    1
    // 1. CREATE a batchSize variable
    2
    int batchSize = 400;
    3
    
    
    4
    var context = new EntityContext();
    5
    6
    for(int i = 0; i <= 2000; i++)
    7
    {
    8
        // 2. CALL SaveChanges before creating a new batch
    9
        if (i != 0 && i%batchSize == 0)
    10
        {
    11
            context.SaveChanges();
    12
            context = new EntityContext();
    13
        }
    14
    
    
    15
        var customer = new Customer();
    16
        // ...code...
    17
    
    
    18
        context.Customers.Add(customer);
    19
    }
    20
    21
    // 3. CALL SaveChanges
    22
    context.SaveChanges();
    23
    24
    // 4. Done!
     
     

    Try it online

  • 相关阅读:
    Nginx编译安装及平滑升级
    alertmanager 分组,抑制, 静默
    alertmanager 邮件告警&自定义告警模板
    alertmanager 高可用
    程序运行报错UnicodeDecodeError: 'utf8' codec can't decode byte 0x89 in position 0: invalid start byte
    Postman 导入curl 、导出成curl、导出成对应语言代码
    Python 字符串操作(截取/替换/查找/分割)
    In testLogin: indirect fixture *** doesn‘t exist
    postman 传参传递二进制流文件
    开发经验01
  • 原文地址:https://www.cnblogs.com/freeliver54/p/9507049.html
Copyright © 2011-2022 走看看