Kāpēc jums ir nepieciešams instrumentāls atbalsts taustiņu lapošanai?

Sveiki visiem! Es esmu aizmugursistēmas izstrādātājs, kas raksta mikropakalpojumus Java + Spring. Es strādāju vienā no Tinkoff iekšējām produktu izstrādes komandām.

Kāpēc jums ir nepieciešams instrumentāls atbalsts taustiņu lapošanai?

Mūsu komandā bieži rodas jautājums par vaicājumu optimizēšanu DBVS. Jūs vienmēr vēlaties būt nedaudz ātrāks, taču ne vienmēr varat iztikt ar pārdomāti izveidotiem indeksiem — jums ir jāmeklē daži risinājumi. Vienā no šiem klejojumiem pa tīmekli, meklējot saprātīgas optimizācijas darbam ar datu bāzēm, es atklāju Markusa Vinanda bezgalīgi noderīgais emuārs, grāmatas SQL Performance Explained autors. Šis ir tas retais emuāra veids, kurā varat lasīt visus rakstus pēc kārtas.

Es vēlētos jums iztulkot īsu Markusa rakstu. To zināmā mērā var saukt par manifestu, kura mērķis ir pievērst uzmanību vecajai, bet joprojām aktuālajai nobīdes operācijas veikšanas problēmai atbilstoši SQL standartam.

Dažviet papildināšu autoru ar paskaidrojumiem un komentāriem. Visas šādas vietas saukšu kā “aptuveni”. lielākai skaidrībai

Mazs ievads

Es domāju, ka daudzi cilvēki zina, cik problemātisks un lēns ir darbs ar lapu atlasi, izmantojot nobīdi. Vai zinājāt, ka to var diezgan viegli nomainīt ar efektīvāku dizainu?

Tātad nobīdes atslēgvārds liek datubāzei izlaist pirmos n ierakstus pieprasījumā. Tomēr datu bāzei vēl ir jānolasa šie pirmie n ieraksti no diska, norādītajā secībā (piezīme: izmantojiet kārtošanu, ja tas ir norādīts), un tikai tad būs iespējams atgriezt ierakstus no n+1. Interesantākais ir tas, ka problēma nav konkrētajā DBVS ieviešanā, bet gan sākotnējā definīcijā saskaņā ar standartu:

…rindas vispirms tiek sakārtotas atbilstoši un pēc tam ierobežo, atmetot rindu skaitu, kas norādīts no sākuma...
-SQL:2016, 2. daļa, 4.15.3. Atvasinātās tabulas (piezīme: pašlaik visbiežāk izmantotais standarts)

Galvenais šeit ir tas, ka nobīde aizņem vienu parametru - izlaižamo ierakstu skaitu, un tas arī viss. Saskaņā ar šo definīciju DBVS var tikai izgūt visus ierakstus un pēc tam izmest nevajadzīgos. Acīmredzot šī kompensācijas definīcija liek mums veikt papildu darbu. Un pat nav svarīgi, vai tas ir SQL vai NoSQL.

Tikai nedaudz vairāk sāpju

Problēmas ar kompensāciju nebeidzas, un lūk, kāpēc. Ja starp divu datu lappušu nolasīšanu no diska cita darbība ievieto jaunu ierakstu, kas notiks šajā gadījumā?

Kāpēc jums ir nepieciešams instrumentāls atbalsts taustiņu lapošanai?

Ja nobīde tiek izmantota, lai izlaistu ierakstus no iepriekšējām lappusēm, tad, pievienojot jaunu ierakstu starp dažādu lappušu lasījumiem, jūs, visticamāk, iegūsit dublikātus (piezīme: tas ir iespējams, ja mēs lasām lapu pa lappusei, izmantojot secību pēc konstrukcijas, tad mūsu izvades vidū tas var iegūt jaunu ierakstu).

Attēls skaidri parāda šo situāciju. Bāze nolasa pirmos 10 ierakstus, pēc tam tiek ievietots jauns ieraksts, kas visus nolasītos ierakstus nobīda par 1. Tad bāze paņem jaunu lapu no nākamajiem 10 ierakstiem un sāk nevis no 11., kā vajadzētu, bet no 10., dublē šo ierakstu. Ar šī izteiciena lietošanu ir saistītas arī citas anomālijas, taču šī ir visizplatītākā.

Как мы уже выяснили, это не проблемы конкретной СУБД или их реализаций. Проблема — в определении пагинации по стандарту SQL. Мы говорим СУБД, какую страницу нужно достать или как много записей пропустить. База просто не в состоянии оптимизировать такой запрос, так как для этого слишком мало информации.

Ir arī vērts precizēt, ka šī problēma nav saistīta ar konkrētu atslēgvārdu, bet gan ar vaicājuma semantiku. Ir vēl vairākas sintakses, kas pēc to problemātiskā rakstura ir identiskas:

  • Nobīdes atslēgvārds ir tāds, kā minēts iepriekš.
  • Divu atslēgvārdu konstrukcija ierobežojums [offset] (lai gan pats ierobežojums nav tik slikts).
  • Filtrēšana pēc apakšējām robežām, pamatojoties uz rindu numerāciju (piemēram, row_number(), rownum utt.).

Visi šie izteicieni vienkārši norāda, cik rindu ir jāizlaiž, bez papildu informācijas vai konteksta.

Vēlāk šajā rakstā nobīdes atslēgvārds tiek izmantots kā visu šo opciju kopsavilkums.

Dzīve bez OFFSET

Tagad iedomāsimies, kāda būtu mūsu pasaule bez visām šīm problēmām. Izrādās, ka dzīve bez nobīdes nav tik grūta: ar atlasi varat atlasīt tikai tās rindas, kuras mēs vēl neesam redzējuši (piezīme: tas ir, tās, kuras nebija iepriekšējā lapā), izmantojot nosacījumu kur.

Šajā gadījumā mēs sākam no tā, ka atlases tiek izpildītas pasūtītā komplektā (vecais labais pasūtījums pēc). Tā kā mums ir pasūtīts komplekts, mēs varam izmantot diezgan vienkāršu filtru, lai iegūtu tikai tos datus, kas atrodas aiz iepriekšējās lapas pēdējā ieraksta:

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

Tas ir viss šīs pieejas princips. Protams, lietas kļūst jautrākas, šķirojot pēc daudzām kolonnām, taču ideja joprojām ir tāda pati. Ir svarīgi atzīmēt, ka šis dizains ir piemērots daudziem NoSQL-lēmumi.

Šo pieeju sauc par meklēšanas metodi vai atslēgu kopas lapošanu. Tas atrisina peldošā rezultāta problēmu (piezīme: iepriekš aprakstītā situācija ar rakstīšanu starp lappušu lasīšanu) un, protams, tas, kas mums visiem patīk, darbojas ātrāk un stabilāk nekā klasiskais nobīde. Stabilitāte slēpjas faktā, ka pieprasījuma apstrādes laiks nepalielinās proporcionāli pieprasītās tabulas skaitam (piezīme: ja vēlaties uzzināt vairāk par dažādu lappušu veidošanas pieeju darbību, varat apskatiet autora prezentāciju. Tur varat arī atrast dažādu metožu salīdzinošos etalonus).

Viens no slaidiem runā par toka lapošana pēc atslēgām, protams, nav visvarena – tai ir savi ierobežojumi. Vissvarīgākais ir tas, ka viņai nav iespēju lasīt nejaušas lapas (piezīme: nekonsekventi). Tomēr bezgalīgas ritināšanas laikmetā (piezīme: priekšpusē) tā nav tik liela problēma. Lapas numura norādīšana klikšķināšanai jebkurā gadījumā ir slikts lēmums lietotāja interfeisa dizainā (piezīme: raksta autora viedoklis).

Kā ar instrumentiem?

Lappuses uz taustiņiem bieži vien nav piemērotas, jo šai metodei trūkst instrumentālā atbalsta. Vairums izstrādes rīku, tostarp dažādi ietvari, neļauj izvēlēties, kā tieši tiks veikta lappušu veidošana.

Situāciju pasliktina fakts, ka aprakstītajai metodei ir nepieciešams pilnīgs atbalsts izmantotajās tehnoloģijās - no DBVS līdz AJAX pieprasījuma izpildei pārlūkprogrammā ar bezgalīgu ritināšanu. Tā vietā, lai norādītu tikai lapas numuru, tagad ir jānorāda taustiņu kopa visām lapām vienlaikus.

Tomēr to ietvaru skaits, kas atbalsta atslēgu lappušu izkārtošanu, pakāpeniski pieaug. Lūk, kas mums šobrīd ir:

(Piezīme: dažas saites tika noņemtas, jo tulkošanas brīdī dažas bibliotēkas nebija atjauninātas kopš 2017.–2018. gada. Ja jūs interesē, varat apskatīt oriģinālo avotu.)

Tieši šajā brīdī ir nepieciešama jūsu palīdzība. Ja jūs izstrādājat vai atbalstāt ietvaru, kurā tiek izmantota lappušu šķirošana, es lūdzu, es aicinu, es lūdzu jūs nodrošināt vietējo atbalstu lapošanai uz atslēgām. Ja jums ir jautājumi vai nepieciešama palīdzība, es ar prieku palīdzēšu (forums, Twitter, Saziņas veidlapa) (piezīme: pēc savas pieredzes ar Markusu varu teikt, ka viņš ir patiesi entuziasts par šīs tēmas izplatīšanu).

Ja izmantojat jau gatavus risinājumus, kas, jūsuprāt, ir cienīgi, lai atbalstītu lappušu šķirošanu pēc atslēgām, izveidojiet pieprasījumu vai pat piedāvājiet gatavu risinājumu, ja iespējams. Varat arī izveidot saiti uz šo rakstu.

Secinājums

Iemesls, kāpēc tik vienkārša un noderīga pieeja kā lappušu šķirošana pēc atslēgām nav plaši izplatīta, nav tas, ka to būtu tehniski grūti īstenot vai tas prasa lielas pūles. Galvenais iemesls ir tas, ka daudzi ir pieraduši redzēt un strādāt ar nobīdi - šo pieeju nosaka pats standarts.

Rezultātā daži cilvēki domā par pieejas maiņu lappušu veidošanai, un tāpēc instrumentālais atbalsts no ietvariem un bibliotēkām attīstās slikti. Tāpēc, ja ideja un mērķis par bezkompensācijas lappusi jums ir tuva, palīdziet to izplatīt!

Avots: https://use-the-index-luke.com/no-offset
Autors: Markuss Vinands

Avots: www.habr.com

Pievieno komentāru