EF требуется ~ 90 секунд для выполнения запроса к одной таблице - PullRequest
2 голосов
/ 18 октября 2019

У меня следующий запрос в Entity Framework Core:

private static List<Provider> JoinProvTables(State state)
{
   using (var db = new ProvContext(state))
   {
        return db.Provider
            //.Include(provider => provider.ServLocation)
            .ToList();
   }
}

public static IEnumerable<T> Name(State state, string first, string last, string middle = null)
{
          return (IEnumerable<T>)JoinProvTables(state)
                .Where(provider => String.Equals(provider.FirstName, first, StringComparison.OrdinalIgnoreCase)
                      && String.Equals(provider.LastName, last, StringComparison.OrdinalIgnoreCase))
                .ToList();
}

Этот запрос на самом деле немного больше в коде (логика, которую я вырезал, та же логика, но для разных объединений таблиц), чем та, которую явыше, но сейчас я смотрю только на одну часть, где я хочу получить чье-то имя. Эта часть, где проблема. Запрос здесь занимает 80-90 секунд, чтобы пройти ~ 65 000 строк.

И метод JoinPRNTables будет только ухудшаться по мере его дальнейшего развития, потому что мне нужны данные о 5-6 связанных таблицах, которые у меня есть. еще не Included() ред. Из-за варианта использования моего приложения каждый запрос всегда будет нуждаться в данных из всех включенных таблиц, это не то, что я могу обойти.

Вот контекст:

namespace Company.Domain.Application.Models
{
    using Microsoft.EntityFrameworkCore;

    public class ProvContext : DbContext
    {
        private string _state;

        public ProvContext(State state)
        {
            _state = state.ToString().ToUpper();
        }

        public DbSet<Provider> Provider { get; set; }
        public DbSet<ServLocation> ServLocation { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(
                $"server=SERVER;database=DATABASE_{_state};trusted_connection=true;");
        }
    }
}

ИМодель провайдера:

namespace Company.Domain.Application.Models
{
    using System;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;

    [Table("TABLE", Schema = "SCHEMA")]
    public class PRN_Provider
    {
        [Key]
        public int ProvID { get; set; }
        public PRN_ServLocation PRN_ServLocation { get; set; }

        [Display(Name = "First Name")]
        [StringLength(100)]
        public string FirstName { get; set; }

        [Display(Name = "Middle Name")]
        [StringLength(100)]
        public string MiddleName { get; set; }

        [Display(Name = "Last Name")]
        [StringLength(100)]
        public string LastName { get; set; }

        //... more of the same structure for fields
   }
}

Можно ли сократить время запроса? Когда я называю это QueryBy<PRN_Provider>.Name(state, "JOHN", "SMITH").FirstOrDefault().FirstName, это занимает 90 секунд, и личная информация, такая как FirstName и т. Д., Находится в первой и единственной таблице, используемой в данный момент, поэтому на данный момент нет никаких JOIN-соединений или связанных таблиц. Мой Scrum-мастер говорит мне, что 90 секунд в порядке, но я все еще хотел бы знать, есть ли способ сократить время.

1 Ответ

3 голосов
/ 18 октября 2019

Вы загружаете все в память. Просто не делай этого.

Ваша проблема начинается с using (var db = new ProvContext(state)), это заставляет вас загружать всю таблицу.

  • Используйте внедрение зависимостей или другую стратегию, чтобы оставить контекст открытым.

  • убедитесь, что вы выполняете .First() непосредственно на IQueryable

public static IQueryable<T> Name(State state, string first, string last, string middle = null)
{
      return // (IEnumerable<T>)JoinProvTables(state)
             db.Provider  // -- manage the lifetime some other way
            .Where(provider => String.Equals(provider.FirstName, first, StringComparison.OrdinalIgnoreCase)
                  && String.Equals(provider.LastName, last, StringComparison.OrdinalIgnoreCase))
           // .ToList()  -- this takes all that time
            ;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...