Inicialização EF extremamente lenta - 15 minutos

Há algum tempo, criei um sistema no qual o usuário pode definir categorias com arquivos personalizados para alguns objetos. Então, cada objeto tem FieldValue com base em sua categoria. Classes abaixo:

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

Na minha máquina de desenvolvimento (i5, 16bg ram e unidade ssd), o banco de dados (no SqlExpress) com 4 categorias, cada um com 5-6 campos, 10k registros, a primeira consulta leva cerca de 15s. Essa primeira consulta é

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();

Eu faço isso para carregar tudo na memória. Então, trabalho na lista em cache e apenas escrevo as alterações no banco de dados. Eu faço isso, porque o usuário pode executar a pesquisa com filtro em cada FieldValue. A consulta ao banco de dados sempre foi muito lenta - essa parte, no entanto, funciona muito bem.

Problema ocorre mais tarde. Alguns clientes definiram 6 categorias com mais de 20 campos em cada um e armazenam mais de 70k registros; a inicialização leva mais de 15 minutos às vezes. Depois disso, não há diferença na velocidade entre 5k e 50k.

Todas as técnicas para melhorar o código EF A primeira vez que iniciei o processo considera principalmente o cache de criação de exibição, aumentando o EF e assim por diante, mas nesse caso o tempo de inicialização aumenta após a adição de mais registros, não mais tipos de entidades.

Sei que isso é causado pela complexidade do esquema, mas há alguma maneira de acelerar isso? Felizmente, este é o Windows Service, portanto, uma vez iniciado, ele dura semanas, mas ainda assim.

Devo largar o EF para a primeira carga e fazê-lo em SQL puro? Devo fazer isso em lotes? Devo mudar EF para nHibernate? Ou alguma outra coisa? Em servidores virtualizados durante a execução desta linha, este programa maximiza a CPU (não o servidor SQL, mas o meu aplicativo).

Tentei carregar apenas objetos e depois carregar suas propriedades mais tarde. Isso foi um pouco mais rápido (mas não notavelmente) em bancos de dados pequenos, mas é ainda mais lento em bancos de dados maiores. Qualquer ajuda é apreciada, mesmo que a resposta seja "aguarde e aguarde".

questionAnswers(1)

yourAnswerToTheQuestion