Эти шаги позволили увеличить время загрузки большой базы данных с 12 до 1 минуты.

орое время назад я создал систему, в которой пользователь может определять категории с настраиваемыми полями для некоторых объектов. Затем каждый объект имеет FieldValue в зависимости от его категории. Классы ниже:

public class DbCategory
    {
        public int Id { get; set; }

        [Required]
        public string Name { get; set; }

        [Required]
        public TextDbField MainField { get; set; }
        public List<DbField> Fields { get; set; }
    }

 public class DbObject
    {
        public int Id { get; set; }
        public byte[] Bytes { get; set; }

        [Required]
        public DbCategory Category { get; set; }

        public TextDbFieldValue MainFieldValue { get; set; }
        public List<DbFieldValue> FieldsValues { get; set; }
    }

public abstract class DbField
    {
        public int Id { get; set; }

        [Required]
        public string Name { get; set; }

        [Required]
        public bool Required { get; set; }


    }


    public class IntegerDbField : DbField
    {
        public int? Minimum { get; set; }
        public int? Maximum { get; set; }
    }

    public class FloatDbField : DbField
    {
        public double? Minimum { get; set; }
        public double? Maximum { get; set; }

    }
//... few other types

  public abstract class DbFieldValue
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public DbField Field { get; set; }

        [JsonIgnore]
        public abstract string Value { get; set; }
    }


    public class IntDbFieldValue : DbFieldValue
    {
        public int? IntValue { get; set; }

        public override string Value
        {
            get { return IntValue?.ToString(); }
            set
            {
                if (value == null) IntValue = null;
                else IntValue = int.Parse(value);
            }
        }
    }// and other FieldValue types

На моем компьютере разработчика (i5, ram 16bg и диск ssd) база данных (в SqlExpress) с 4 категориями, каждая из которых имеет 5-6 полей, 10 тыс. Записей, первый запрос занимает около 15 с. Этот первый запрос

var result = db.Objects
     .Include(s => s.Category)
     .Include(s => s.Category.MainField)
     .Include(s => s.MainFieldValue.Field)
     .Include(s => s.FieldsValues.Select(f => f.Field))
     .Where(predicate ?? AlwaysTrue)
     .ToArray();

Я делаю это, чтобы загрузить все в память. Затем я работаю с кэшированным списком и просто записываю изменения в базу данных. Я делаю это, потому что пользователь может выполнять поиск с фильтром по каждому FieldValue. Запросы к базе данных каждый раз оказывались слишком медленными - однако эта часть работает довольно хорошо.

Проблема возникает позже. Некоторые клиенты определили 6 категорий с 20+ полями в каждой и хранят более 70 тыс. Записей, запуск иногда занимает более 15 минут. После этого нет разницы в скорости между 5k и 50k.

Каждый метод улучшения кода EF Первое время запуска, которое я обнаружил, касается главным образом кэширования создания представления, создания EF и т. Д., Но в этом случае время запуска увеличивается после добавления большего количества записей, а не большего числа типов сущностей.

Я понимаю, что это вызвано сложностью схемы, но есть ли способ ускорить это? К счастью, это служба Windows, поэтому, как только она запускается, она работает неделями, но все же.

Должен ли я сбросить EF для первой загрузки и сделать это на чистом SQL? Должен ли я делать это партиями? Стоит ли менять EF на nHibernate? Или что-то другое? На виртуализированных серверах во время выполнения этой строки эта программа максимально загружает ЦП (не SQL-сервер, а мое приложение).

Я попытался загрузить только объекты, а затем загрузить их свойства позже. Это было немного быстрее (но не заметно) для небольших баз данных, но еще медленнее для больших. Любая помощь приветствуется, даже если ответ «смирись и жди».

Ответы на вопрос(1)

Ваш ответ на вопрос