Hoekom het jy instrumentele ondersteuning nodig vir paginering op sleutels?

Hi almal! Ek is 'n backend-ontwikkelaar wat mikrodienste in Java + Spring skryf. Ek werk in een van die interne produkontwikkelingspanne by Tinkoff.

Hoekom het jy instrumentele ondersteuning nodig vir paginering op sleutels?

In ons span ontstaan ​​die vraag oor die optimalisering van navrae in 'n DBBS dikwels. Jy wil altyd 'n bietjie vinniger wees, maar jy kan nie altyd klaarkom met deurdagte saamgestelde indekse nie - jy moet 'n paar oplossings soek. Tydens een van hierdie omswerwinge op die web op soek na redelike optimalisering wanneer daar met databasisse gewerk word, het ek gevind Marcus Wynand se eindelose nuttige blog, skrywer van SQL Performance Explained. Dit is daardie seldsame tipe blog waarin jy al die artikels in 'n ry kan lees.

Ek wil graag 'n kort artikel deur Marcus vir jou vertaal. Dit kan tot 'n mate 'n manifes genoem word wat die aandag wil vestig op die ou, maar steeds relevante probleem van die uitvoering van die offset-operasie volgens die SQL-standaard.

Op sommige plekke sal ek die skrywer aanvul met verduidelikings en kommentaar. Ek sal na al sulke plekke verwys as "ongeveer." vir meer duidelikheid

Klein inleiding

Ek dink baie mense weet hoe problematies en stadig werk met bladsykies via offset is. Het jy geweet dat dit redelik maklik vervang kan word met 'n meer doeltreffende ontwerp?

Dus, die offset-sleutelwoord vertel die databasis om die eerste n rekords in die versoek oor te slaan. Die databasis moet egter steeds hierdie eerste n rekords vanaf skyf lees, in die gegewe volgorde (let wel: pas sortering toe as dit gespesifiseer is), en eers dan sal dit moontlik wees om rekords vanaf n+1 terug te stuur. Die interessantste ding is dat die probleem nie in die spesifieke implementering in die DBBS is nie, maar in die oorspronklike definisie volgens die standaard:

…die rye word eers gesorteer volgens die en dan beperk deur die aantal rye wat in die gespesifiseer is, te laat val van die begin af...
-SQL:2016, Deel 2, 4.15.3 Afgeleide tabelle (let wel: tans die mees gebruikte standaard)

Die belangrikste punt hier is dat verrekening 'n enkele parameter neem - die aantal rekords om oor te slaan, en dit is dit. Na aanleiding van hierdie definisie kan die DBBS net al die rekords ophaal en dan die onnodige weggooi. Dit is duidelik dat hierdie definisie van verreken ons dwing om ekstra werk te doen. En dit maak nie eers saak of dit SQL of NoSQL is nie.

Net 'n bietjie meer pyn

Die probleme met offset eindig nie daar nie, en hier is hoekom. As, tussen die lees van twee bladsye van data vanaf skyf, 'n ander bewerking 'n nuwe rekord invoeg, wat sal in hierdie geval gebeur?

Hoekom het jy instrumentele ondersteuning nodig vir paginering op sleutels?

Wanneer offset gebruik word om rekords van vorige bladsye oor te slaan, in die situasie van die byvoeging van 'n nuwe rekord tussen leeswerk van verskillende bladsye, sal jy heel waarskynlik duplikate kry (let wel: dit is moontlik wanneer ons bladsy vir bladsy lees deur die volgorde volgens konstruk te gebruik, dan in die middel van ons uitset kan dit 'n nuwe inskrywing kry).

Die figuur beeld hierdie situasie duidelik uit. Die basis lees die eerste 10 rekords, waarna 'n nuwe rekord ingevoeg word, wat alle gelees rekords met 1 verreken. Dan neem die basis 'n nuwe bladsy van die volgende 10 rekords en begin nie vanaf die 11de, soos dit moet nie, maar vanaf die 10de, dupliseer hierdie rekord. Daar is ander afwykings wat verband hou met die gebruik van hierdie uitdrukking, maar dit is die algemeenste.

Soos ons reeds uitgevind het, is dit nie probleme van 'n spesifieke DBBS of hul implementerings nie. Die probleem is om paginering volgens die SQL-standaard te definieer. Ons vertel die DBBS watter bladsy om te gaan haal of hoeveel rekords om oor te slaan. Die databasis is eenvoudig nie in staat om so 'n versoek te optimaliseer nie, aangesien daar te min inligting hiervoor is.

Dit is ook die moeite werd om te verduidelik dat dit nie 'n probleem met 'n spesifieke sleutelwoord is nie, maar eerder met die semantiek van die navraag. Daar is nog verskeie sintakse wat identies is in hul problematiese aard:

  • Die offset-sleutelwoord is soos vroeër genoem.
  • 'n Konstruksie van twee sleutelwoorde limiet [offset] (hoewel limiet self nie so erg is nie).
  • Filtreer volgens ondergrense, gebaseer op rynommering (byvoorbeeld, ry_nommer(), rynommer, ens.).

Al hierdie uitdrukkings sê eenvoudig vir jou hoeveel reëls om oor te slaan, geen bykomende inligting of konteks nie.

Later in hierdie artikel word die offset-sleutelwoord gebruik as 'n opsomming van al hierdie opsies.

Lewe sonder OFFSET

Kom ons stel ons nou voor hoe ons wêreld sou wees sonder al hierdie probleme. Dit blyk dat die lewe sonder offset nie so moeilik is nie: met 'n kies kan jy net daardie rye kies wat ons nog nie gesien het nie (let wel: dit wil sê dié wat nie op die vorige bladsy was nie), met behulp van 'n toestand waarin.

In hierdie geval begin ons by die feit dat seleksies uitgevoer word op 'n geordende stel (goeie ou orde deur). Aangesien ons 'n geordende stel het, kan ons 'n redelik eenvoudige filter gebruik om slegs die data te kry wat agter die laaste rekord van die vorige bladsy is:

    SELECT ...
    FROM ...
    WHERE ...
    AND id < ?last_seen_id
    ORDER BY id DESC
    FETCH FIRST 10 ROWS ONLY

Dit is die hele beginsel van hierdie benadering. Natuurlik word dinge meer pret as jy volgens baie kolomme sorteer, maar die idee is steeds dieselfde. Dit is belangrik om daarop te let dat hierdie ontwerp op baie van toepassing is NoSQL-besluite.

Hierdie benadering word soekmetode of sleutelsetpaginering genoem. Dit los die probleem met swewende resultate op (let wel: die situasie met skryf tussen bladsylesings wat vroeër beskryf is) en, natuurlik, waarvan ons almal hou, dit werk vinniger en meer stabiel as die klassieke offset. Stabiliteit lê in die feit dat die versoekverwerkingstyd nie toeneem in verhouding tot die nommer van die gevraagde tabel nie (let wel: as jy meer wil leer oor die werk van verskillende benaderings tot paginering, kan jy kyk deur die skrywer se aanbieding. U kan ook vergelykende maatstawwe vir verskillende metodes daar vind).

Een van die skyfies daaroor praatdat paginering deur sleutels natuurlik nie almagtig is nie – dit het sy beperkings. Die belangrikste is dat sy nie die vermoë het om willekeurige bladsye te lees nie (let wel: inkonsekwent). In die era van eindelose blaai (let wel: aan die voorkant), is dit egter nie so 'n probleem nie. Om 'n bladsynommer te spesifiseer om te klik is in elk geval 'n slegte besluit in UI-ontwerp (let wel: mening van die skrywer van die artikel).

Wat van die gereedskap?

Paginering op sleutels is dikwels nie geskik nie weens die gebrek aan instrumentele ondersteuning vir hierdie metode. Die meeste ontwikkelingsinstrumente, insluitend verskeie raamwerke, laat jou nie toe om presies te kies hoe paginering uitgevoer sal word nie.

Die situasie word vererger deur die feit dat die beskryfde metode end-tot-end-ondersteuning vereis in die tegnologieë wat gebruik word - van die DBMS tot die uitvoering van 'n AJAX-versoek in die blaaier met eindelose blaai. In plaas daarvan om net die bladsynommer te spesifiseer, moet jy nou 'n stel sleutels vir alle bladsye op een slag spesifiseer.

Die aantal raamwerke wat paginering op sleutels ondersteun, groei egter geleidelik. Hier is wat ons op die oomblik het:

(Let wel: sommige skakels is verwyder as gevolg van die feit dat sommige biblioteke ten tyde van vertaling nie sedert 2017-2018 opgedateer is nie. As jy belangstel, kan jy na die oorspronklike bron kyk.)

Dit is op hierdie oomblik dat u hulp nodig is. As jy 'n raamwerk ontwikkel of ondersteun wat enige gebruik maak van paginering, dan vra ek, ek smeek jou om inheemse ondersteuning vir paginering op sleutels te verskaf. As jy vrae het of hulp nodig het, sal ek graag help (форум, Twitter, Kontak Vorm) (let wel: uit my ervaring met Marcus kan ek sê dat hy regtig entoesiasties is om hierdie onderwerp te versprei).

As jy klaargemaakte oplossings gebruik wat jy dink waardig is om ondersteuning vir paginering deur sleutels te hê, skep 'n versoek of bied selfs 'n klaargemaakte oplossing, indien moontlik. Jy kan ook skakel na hierdie artikel.

Gevolgtrekking

Die rede waarom so 'n eenvoudige en nuttige benadering soos paginering deur sleutels nie wydverspreid is nie, is nie dat dit moeilik is om tegnies te implementeer of enige groot moeite verg nie. Die hoofrede is dat baie daaraan gewoond is om met offset te sien en te werk - hierdie benadering word deur die standaard self bepaal.

Gevolglik dink min mense daaraan om die benadering tot paginering te verander, en as gevolg hiervan ontwikkel instrumentele ondersteuning van raamwerke en biblioteke swak. Daarom, as die idee en doelwit van verrekenvrye paginering naby jou is, help om dit te versprei!

Bron: https://use-the-index-luke.com/no-offset
Skrywer: Markus Winand

Bron: will.com

Voeg 'n opmerking