sql >> Databáze >  >> RDS >> Sqlserver

Efektivní způsob získání @@rowcount z dotazu pomocí row_number

V průběhu let se hromada potu vývojářů dostala do efektivních stránkovacích sad výsledků. Přesto neexistuje žádná odpověď - záleží na vašem případu použití. Část případu použití je efektivní získání vaší stránky, část je zjištění, kolik řádků je v kompletní sadě výsledků. Omlouvám se, pokud jsem trochu zabloudil do stránkování, ale oba jsou v mé mysli docela úzce propojeni.

Existuje mnoho strategií, z nichž většina je špatná, pokud máte jakýkoli objem dat a neodpovídají případu použití. I když toto není úplný seznam, níže jsou uvedeny některé z možností......

Spustit samostatné Count(*)

  • spusťte samostatný dotaz, který provede jednoduchý "select count(*) from MyTable"
  • jednoduché a snadné pro malý stůl
  • dobré na nefiltrované velké tabulce, která je buď úzká, nebo má kompaktní neseskupený index, který můžete použít
  • zlomí se, když máte komplikované WHERE/JOIN kritéria, protože spustíte WHERE/JOIN dvakrát je drahé.
  • na širokém indexu se rozpadá, protože se zvyšuje počet přečtení.

Zkombinujte ROW_Number() OVER() a COUNT(1) OVER(PARTITION By 1)

  • Toto navrhl @RBarryYoung. Výhodou je, že se snadno implementuje a je velmi flexibilní.
  • Nevýhodou je, že existuje mnoho důvodů, proč se to může extrémně rychle prodražit.
  • Například v databázi, se kterou právě pracuji, je tabulka médií s asi 6000 řádky. Není nijak zvlášť široký, má celočíselný seskupený PK a také kompaktní jedinečný index. Přesto jednoduchý COUNT(*) OVER(PARTITION BY 1) as TotalRows výsledkem je ~12 000 přečtení. Porovnejte to s jednoduchým SELECT COUNT(*) FROM Media -- 12 přečtení. Wowzerové.

Tabulky temp / proměnné tabulky

  • Existuje mnoho strategií, které využívají sadu výsledků a vkládají příslušné klíče nebo segmenty výsledků do dočasných tabulek / proměnných tabulek.
  • U malých/středně velkých sad výsledků to může poskytnout skvělé výsledky.
  • Tento typ strategie funguje téměř na jakékoli platformě/verzi SQL.
  • Operovat se sadou výsledků vícekrát (dost často požadavek) je také snadné.
  • Při práci s velkými sadami výsledků je nevýhodou ... vložení několika milionů řádků do dočasné tabulky má své náklady.
  • Problém je v tom, že ve vysokoobjemovém systému může být tlak na TempDB docela faktorem a tabulky temp v TempDB efektivně fungují.

Gaussův součet / číslo dvojitého řádku

  • Tento nápad se opírá o podmnožinu něco, na co přišel matematik Gauss (jak sečíst řadu čísel). Podmnožinou je způsob, jak získat počet řádků z libovolného bodu v tabulce.
  • Z řady čísel (Row_Number() ) počet řádků pro 1 až N je (N + 1) - 1 . Více vysvětlení v odkazech.
  • Zdá se, že vzorec by se vyrovnal pouze N, ale pokud se budete držet vzorce, dojde k zajímavým věcem, můžete zjistit počet řádků ze stránky uprostřed tabulky.
  • Čistým výsledkem je, že uděláte ROW_Number() OVER(Order by ID) a ROW_Number() OVER(Order by ID DESC) pak sečtěte dvě čísla a odečtěte 1.
  • Použitím mé tabulky Média jako příkladu mé čtení kleslo z 12 000 na přibližně 75.
  • Na větší stránce jste nakonec data mnohokrát opakovali, ale posun ve čtení může stát za to.
  • Netestoval jsem to na příliš mnoha scénářích, takže se to může rozpadnout v jiných scénářích.

Nahoře (@n) / NASTAVIT POČET ŘÁDKŮ

  • Toto nejsou konkrétní strategie samy o sobě, ale jsou to optimalizace založené na tom, co víme o optimalizátoru dotazů.
  • Kreativní použití Top(@n) [top může být proměnná v SQL 2008] nebo SET ROWCOUNT může snížit vaši pracovní sadu ...i když vytahujete prostřední stránku sady výsledků, stále můžete zúžit výsledek
  • Tyto nápady fungují díky chování optimalizátoru dotazů ... aktualizace service pack/oprava hotfix může toto chování změnit (i když pravděpodobně ne).
  • V určitých případech může být SET ROWCOUNT trochu přesný
  • Tato strategie nepočítá se získáním plného počtu řádků, pouze zefektivňuje stránkování

Co má tedy vývojář dělat?

Přečtěte si můj dobrý muž, čtěte. Zde je několik článků, o které jsem se opřel...

Doufám, že to pomůže.



  1. percentil podle COUNT(DISTINCT) s korelací WHERE funguje pouze s pohledem (nebo bez DISTINCT)

  2. Mysql Sloupec Průměrný čas?

  3. MariaDB - nelze se přihlásit jako root

  4. VĚŠTEC. Autentizace pomocí LDAP vždy vrátí -16