Paginacja po stronie SQL - bardzo wolne działanie jeśli strona jest wysoka

0

Witam.
Zauważyłem pewien problem i nie bardzo wiem dlaczego występuje. Pierwszy raz zrobiłem API, w którym paginacja jest po stronie SQLa. Wcześniej miałem raczej umiarkowaną ilość danych i mogłem sobie to ogarnąć za pomocą linq.

ZAPYTANIE - 52 strona to guzik Last page w SPA (Angular). Ja wiem, że nikt nie klika stron dla oglądania danych ale na ostatnią ktoś może przejść.

select 
* 
from 
Documents 
where Type = 308 
and DocumentDate between '2021-02-17' and '2021-02-17'
order by Id desc
offset 52 rows
fetch next 10 rows only;

select count(*)
from Documents 
where Type  = 308
and DocumentDate  between '2021-02-17' and '2021-02-17'

DAPPER - gdzieś w jakimś artykule widziałem ten sposób wyciągania wielu zapytań na raz

var documents = new DocumentsResponse();

using (var db = _dbConnectionFactory.CreateCompanyConnection())
{
    using (var multi = await db.QueryMultipleAsync(query, new { Page = filter.Limit * filter.Page, filter.Limit, filter.Type, filter.StartDate, filter.EndDate }))
    {
        documents.Data = multi.Read<Document>();
        documents.DataLength = multi.ReadFirst<int>();
    }
}

return documents;

CZAS
Strona 1 = 2.31s
Strona 2 = 2.22s
Strona 3 = 2.75s
Strona 4 = 3.42s
Ze strony 4 na ostatnią = 24.90s
Ze strony 1 na ostatnią = 23.64s
Z ostatniej na 1 = 1.94s

Wszystko na localhost, w debugu. API w .NET 5, SPA w Angular 11.

0

Ale to są zmierzone czasy samej bazy?

0

Nope. To są czasy z przeglądarki. Mam wrażenie, że problemem jest sam Dapper, ponieważ Management robi to błyskawicznie.

1

Jak to są czasy z przeglądarki, to może to być:

  • serwer WWW;
  • kod Twojej aplikacji;
  • kod biblioteki zewnętrznej (np. Dappera);
  • SQL wykonywany na bazie.

Ostatnią opcję odrzucasz, ale nadal pozostają co najmniej trzy elementy. Zmierz wydajność samego Dappera.

0

@AdamWox: Weryfikowałeś SQL Profiler czy przełączając się po stronach, idzie poprawne zapytanie do bazy? To zapytanie, które podałeś. jest pisane z palca czy wygenerowane przez Dappera?

0

Okazało się to dopiero jak wrzuciłem posta. Da się coś z tym zrobić? To jest bug czy taką ma wydajność dapper? — AdamWox

O dapperze nie wiem nic.

Ale już spotykałem interfejsy, które wyżej udostępniały interfejs z oknem / paginacją - tyle że pod spodem select *
Ktoś chciał szybciej wydać, klient nalegał, potem się "zapomniało" zrobić po bożemu.

Sprawdziłeś, ze kwerenda w realnej pracy jest taka, jakiej się spodziewasz?
Np historycznie MS-SQL miał tematy stronicowania BARDZO RÓŻNIE / kiepsko / niemal wcale 2005 /2008Rcoś 2012 / itd.
Być może jakaś warstwa musi być uświadomiona, że pracuje z nowoczesną wersją?

0

Okazuje się, że to Dapper i jego QueryMultipleAsync konkretnie przymula. Robiąc te zapytania osobnio.

var documents = new DocumentsResponse();

using (var db = _dbConnectionFactory.CreateCompanyConnection())
{
   documents.Data = await db.QueryAsync<Document>(query1, new { Page = filter.Limit * filter.Page, filter.Limit, filter.Type, filter.StartDate, filter.EndDate }));
   documents.DataLength = await db.QueryFirstOrDefaultAsync<int>(query2, new { Page = filter.Limit * filter.Page, filter.Limit, filter.Type, filter.StartDate, filter.EndDate }));
}

return documents;

Leci bez zająknięcia i ostatnia strona ładuje się w mgnieniu oka 🤔

1 użytkowników online, w tym zalogowanych: 0, gości: 1