Sdílet prostřednictvím


Stránkování

Stránkování odkazuje na načítání výsledků na stránkách, nikoli najednou; to se obvykle provádí u velkých sad výsledků, kde se zobrazí uživatelské rozhraní, které uživateli umožňuje přejít na další nebo předchozí stránku výsledků.

Upozorňující

Bez ohledu na použitou metodu stránkování se vždy ujistěte, že je řazení plně jedinečné. Pokud jsou například výsledky seřazené pouze podle data, ale může existovat více výsledků se stejným datem, výsledky se můžou přeskočit při stránkování, protože jsou uspořádané jinak ve dvou stránkovacích dotazech. Řazení podle data i ID (nebo jakékoli jiné jedinečné vlastnosti nebo kombinace vlastností) způsobí, že řazení je plně jedinečné a zabrání tomuto problému. Mějte na paměti, že relační databáze ve výchozím nastavení nepoužívají žádné řazení, a to ani u primárního klíče.

Posun stránkování

Běžným způsobem implementace stránkování s databázemi je použití Skip a Take (OFFSET a LIMIT v SQL). Vzhledem k velikosti stránky 10 výsledků je možné třetí stránku načíst pomocí EF Core následujícím způsobem:

var position = 20;
var nextPage = context.Posts
    .OrderBy(b => b.PostId)
    .Skip(position)
    .Take(10)
    .ToList();

I když je tato technika velmi intuitivní, má bohužel i některé závažné nedostatky:

  1. Databáze musí stále zpracovávat prvních 20 položek, i když nejsou vráceny do aplikace; tím se vytvoří pravděpodobně významné výpočetní zatížení, které se zvýší s počtem přeskočených řádků.
  2. Pokud dojde ke souběžné aktualizaci, může stránkování skončit přeskočením určitých položek nebo jejich zobrazením dvakrát. Pokud je například položka odebrána, když uživatel přechází ze stránky 2 na 3, celá sada výsledků se posune nahoru a jedna položka se přeskočí.

Stránkování sady klíčů

Doporučenou alternativou ke stránkování založenému na posunu – někdy označované jako stránkování sady klíčů nebo stránkování založené na hledání – je jednoduše použít WHERE klauzuli pro přeskočení řádků místo posunu. To znamená, že si zapamatujte relevantní hodnoty z poslední načtené položky (místo posunu) a požádejte o další řádky za tímto řádkem. Předpokládejme například, že poslední položka na poslední stránce, kterou jsme načítali, měla hodnotu ID 55, stačí udělat toto:

var lastId = 55;
var nextPage = context.Posts
    .OrderBy(b => b.PostId)
    .Where(b => b.PostId > lastId)
    .Take(10)
    .ToList();

Za předpokladu, že je index definovaný PostId, je tento dotaz velmi efektivní a také není citlivý na žádné souběžné změny probíhající v nižších hodnotách ID.

Stránkování sady klíčů je vhodné pro stránkovací rozhraní, ve kterých uživatel prochází dopředu a dozadu, ale nepodporuje náhodný přístup, kde uživatel může přejít na libovolnou konkrétní stránku. Stránkování náhodného přístupu vyžaduje použití stránkování posunu, jak je vysvětleno výše; vzhledem k nedostatkům stránkování posunu pečlivě zvažte, jestli pro váš případ použití skutečně vyžaduje stránkování náhodného přístupu, nebo jestli je dostatečná další/předchozí navigace na stránce. Pokud je potřeba stránkování náhodného přístupu, může robustní implementace použít stránkování sady klíčů při navigaci na další/předchozí stránku a posun navigace při přechodu na jinou stránku.

Více klíčů stránkování

Při použití stránkování sady klíčů je často nutné řadit podle více než jedné vlastnosti. Například následující dotaz stránkuje podle data a ID:

var lastDate = new DateTime(2020, 1, 1);
var lastId = 55;
var nextPage = context.Posts
    .OrderBy(b => b.Date)
    .ThenBy(b => b.PostId)
    .Where(b => b.Date > lastDate || (b.Date == lastDate && b.PostId > lastId))
    .Take(10)
    .ToList();

Tím se zajistí, že další stránka vybere přesně místo, kde skončila předchozí stránka. Při přidání dalších klíčů řazení je možné přidat další klauzule.

Poznámka

Většina databází SQL podporuje jednodušší a efektivnější verzi výše uvedené verze s použitím hodnot řádků: WHERE (Date, Id) > (@lastDate, @lastId). EF Core v současné době nepodporuje vyjádření v dotazech LINQ, kterou sleduje #26822.

Indexy

Stejně jako u jakéhokoli jiného dotazu je pro zajištění dobrého výkonu důležité správné indexování: nezapomeňte mít zavedené indexy, které odpovídají řazení stránkování. Je-li řazení podle více než jednoho sloupce, lze definovat index nad těmito více sloupci; tomu se říká složený index.

Další informace najdete na stránce dokumentace k indexům.

Další prostředky