September 10
Пагинация SQL + EF
1) Обычный запрос на SQL для выборки определенного кол-ва строк (lines) на определенной странице (page)
[HttpGet("/rawSQL")] public async Task<IActionResult> SQL() { using (var context = new ApplicationContext()) { var stopwatch = new Stopwatch(); stopwatch.Start(); int lines = 10; int page = 3; int skip = (page - 1) * lines; var res = await context.Tests.FromSqlInterpolated( quot;SELECT * FROM \"Tests\" WHERE \"Name\" LIKE '%A%' ORDER BY \"Id\" OFFSET {skip} ROWS FETCH NEXT {lines} ROWS ONLY" ).ToListAsync(); stopwatch.Stop(); var timeResult = stopwatch.ElapsedMilliseconds; var result = new { timeResult = quot;Затраченное время {timeResult}", res }; return Ok(result); } }
2) Запрос на EF Core с довольно тупой выборкой :)
[HttpGet("/veryStupidMethod")] public async Task<IActionResult> Dumb() { using (var context = new ApplicationContext()) { var stopwatch = new Stopwatch(); stopwatch.Start(); int lines = 10; int page = 3; int skip = (page - 1) * lines; List<Test> res = await context.Tests.Where(x => x.Name.Contains("A")).ToListAsync(); var a = res.Skip(skip); var b = a.Take(lines); stopwatch.Stop(); var timeResult = stopwatch.ElapsedMilliseconds; var result = new { timeResult = quot;Затраченное время {timeResult}", b }; return Ok(result); } }
3) Запрос с включенным Skip и Take в запрос
[HttpGet("/usingSkipAndTask")] public async Task<IActionResult> UsingSkipAndTask() { using(var context = new ApplicationContext()) { var stopwatch = new Stopwatch(); stopwatch.Start(); IQueryable<Test> TomBombadil = context.Tests; int lines = 10; int page = 3; int skip = (page - 1) * lines; // Условно 3 - 1 = 2 * 10 = 20. 20 Элементов мы пропускаем List<Test> res = await TomBombadil .Where(x => x.Name.Contains("A")) .Skip(skip) .Take(lines) .ToListAsync(); stopwatch.Stop(); var timeResult = stopwatch.ElapsedMilliseconds; var result = new { timeResult = quot;Затраченное время {timeResult}", res }; return Ok(result); } }
В итоге первый раз запрос выполняется ~200мс (что странно!).