Стоит PostgreSQL. В ней таблица с чуть более, чем 300 тысяч строк.
Если я выполняю вот такой запрос в pgAdmin, то он выполняется за доли секунды (~300мс):
SELECT *
FROM public."Movies"
WHERE vote_count > 100
ORDER BY vote_average DESC
LIMIT 10;
Если же выполнить аналогичный запрос в приложении ASP.Net Core, то страница грузится почти минуту (~50c), но если не использовать БД, а просто дать готовую коллекцию аля new Movie[] { ... }
, то загрузка практически мгновенная.
//в классе контроллера
private IMovieRepository repository;
public IActionResult Index()
{
return View(repository.Movies
.Where(m => m.VoteCount > 100)
.OrderByDescending(m => m.VoteAverage)
.Take(10));
}
//класс для работы с данными
public class EFMovieRepository : IMovieRepository
{
private TMDbContext context;
public EFMovieRepository(TMDbContext context)
{
this.context = context;
}
public IEnumerable<Movie> Movies => context.Movies;
}
//класс контекста
public class TMDbContext : DbContext
{
public TMDbContext() : base() { }
public TMDbContext(DbContextOptions<TMDbContext> options) : base(options) { }
public DbSet<Movie> Movies { get; set; }
}
//конфигурация в классе Startup
public Startup(IHostingEnvironment environment)
{
Configuration = new ConfigurationBuilder()
.SetBasePath(environment.ContentRootPath)
.AddJsonFile("appsettings.json")
.Build();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TMDbContext>(option =>
option.UseNpgsql(
Configuration["Data:Movies:ConnectionString"]));
services.AddTransient<IMovieRepository, EFMovieRepository>();
services.AddMvc();
}
Использую Npgsql.EntityFrameworkCore.PostgreSQL
В чём кроется проблема? Может у меня с конфигурацией что-то не так или может запрос надо составлять более правильно? Почему SQL запрос в pgAdmin во столько раз быстрее запроса через провайдера?
UPD: Изменил код метода на:
public string Index()
{
var startTime = DateTime.Now;
var movies = repository.Movies
.Where(m => m.VoteCount > 100)
.OrderByDescending(m => m.VoteAverage)
.Take(10).ToList();
return (DateTime.Now - startTime).TotalSeconds.ToString();
}
Возвращает в среднем 17 секунд.
public IEnumerable<Movie> Movies => context.Movies;
При обращении к этому свойству и получении результатов запроса сначала загрузится весь Movies
, а потом будет применена фильтрация.
Интерфейс IEnumerable находится в пространстве имен System.Collections. Объект IEnumerable представляет набор данных в памяти и может перемещаться по этим данным только вперед. Запрос, представленный объектом IEnumerable, выполняется немедленно и полностью, поэтому получение данных приложением происходит быстро.
При выполнении запроса IEnumerable загружает все данные, и если нам надо выполнить их фильтрацию, то сама фильтрация происходит на стороне клиента.
https://metanit.com/sharp/entityframework/1.4.php
Замените IEnumerable
на IQueryable
. Тогда отбор будет произведён на стороне БД.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Я работаю с элементом Microsoft Ribbon WPF 2010
У меня есть файл на сервере, который я хочу отправить клиентуЯ отправлю его так
Доброе время сутокНе могу победить одну задачку: