Bonjou tout moun! Mwen se yon devlopè backend ekri mikwosèvis nan Java + Spring. Mwen travay nan youn nan ekip devlopman pwodwi entèn yo nan Tinkoff.

Nan ekip nou an, kesyon optimize demann nan yon DBMS souvan rive. Ou toujou vle yon ti kras pi vit, men ou pa ka toujou jwenn ak endèks byen konstwi-ou dwe chèche kèk solisyon. Pandan youn nan pwomnad sa yo atravè entènèt la nan rechèch nan optimize rezonab lè w ap travay ak baz done, mwen te jwenn , otè SQL Pèfòmans Eksplike. Sa a se kalite ki ra nan blog nan ki ou ka li tout atik yo nan yon ranje.
Mwen ta renmen tradui yon ti atik Marcus pou ou. Li ka rele nan yon sèten mezi yon manifès ki ap chèche atire atansyon a fin vye granmoun, men yo toujou enpòtan pwoblèm nan pèfòmans nan nan operasyon an konpanse dapre estanda a SQL.
Nan kèk kote mwen pral konplete otè a ak eksplikasyon ak kòmantè. Mwen pral refere a tout kote sa yo kòm "apeprè." pou plis klè
Yon ti entwodiksyon
Mwen panse ke anpil moun konnen ki jan pwoblèm ak ralanti travay ak paj chwazi atravè konpanse se. Ăske w te konnen ke li ka byen fasil ranplase ak yon konsepsyon ki pi efikas?
Se konsa, mo kle konpanse a di baz done a sote premye n dosye yo nan demann lan. Sepandan, baz done a toujou bezwen li premye n dosye sa yo nan disk, nan lòd yo bay la (nòt: aplike klasman si li espesifye), epi sèlman Lè sa a, li pral posib retounen dosye soti nan n + 1 ivè. Bagay ki pi enteresan an se ke pwoblèm nan se pa nan aplikasyon an espesifik nan DBMS la, men nan definisyon orijinal la dapre estanda a:
âŚranje ranje yo an premye dapre ak Lè sa a limite pa jete kantite ranje ki espesifye nan la depi nan kòmansman...
-SQL:2016, Pati 2, 4.15.3 Tablo ki sòti (nòt: kounye a estanda ki pi itilize)
Pwen kle isit la se ke konpanse pran yon sèl paramèt - kantite dosye yo sote, e se li. Apre definisyon sa a, DBMS ka sèlman rekipere tout dosye yo epi jete sa ki pa nesesè yo. Li evidan, definisyon sa a nan konpanse fòse nou fè travay siplemantè. Epi li pa menm gen pwoblèm si li nan SQL oswa NoSQL.
Jis yon ti kras plis doulè
Pwoblèm yo ak konpanse pa fini la, e isit la se poukisa. Si, ant lekti de paj done ki soti nan disk, yon lòt operasyon foure yon nouvo dosye, kisa ki pral rive nan ka sa a?

Lè konpanse yo itilize pou sote dosye ki soti nan paj anvan yo, nan sitiyasyon an nan ajoute yon nouvo dosye ant lekti nan diferan paj, ou pral gen plis chans jwenn kopi (nòt: sa a se posib lè nou li paj pa paj lè l sèvi avèk lòd la pa konstwi, Lè sa a nan mitan pwodiksyon nou an li ka jwenn yon nouvo antre).
Figi a byen klè dekri sitiyasyon sa a. Baz la li 10 premye dosye yo, apre sa yo mete yon nouvo dosye, ki konpanse tout dosye li pa 1. Lè sa a, baz la pran yon nouvo paj nan 10 dosye kap vini yo epi li kòmanse pa soti nan 11yèm, jan li ta dwe, men soti nan la. 10yèm, kopi dosye sa a. Gen lòt anomali ki asosye ak itilizasyon ekspresyon sa a, men sa a se pi komen an.
Kòm nou te deja dekouvri, sa yo pa pwoblèm nan yon DBMS espesifik oswa aplikasyon yo. Pwoblèm lan se nan defini pagination selon estanda SQL. Nou di DBMS ki paj pou chèche oswa konbyen dosye pou sote. Baz done a tou senpleman pa kapab optimize demann sa a, paske gen twò piti enfòmasyon pou sa a.
Li la tou vo klarifye ke sa a se pa yon pwoblèm ak yon mo kle espesifik, men pito ak semantik la nan rechèch la. Gen plizyè plis sentaks ki idantik nan nati pwoblèm yo:
- Mo kle konpanse a se jan yo mansyone pi bonè.
- Yon konstriksyon de mo kle limite [dekonpanse] (byenke limit tèt li pa tèlman mal).
- Filtrage pa limit pi ba yo, ki baze sou nimero ranje (pa egzanp, row_number(), rownum, elatriye).
Tout ekspresyon sa yo tou senpleman di w konbyen liy pou sote, pa gen plis enfòmasyon oswa kontèks.
Pita nan atik sa a, yo itilize mo kle konpanse kòm yon rezime tout opsyon sa yo.
Lavi san OFFSET
Koulye a, ann imajine kisa mond nou an ta ye san tout pwoblèm sa yo. Li sanble ke lavi san yo pa konpanse pa tèlman difisil: ak yon seleksyon, ou ka chwazi sèlman ranje sa yo ke nou poko wè (nòt: se sa ki pa t 'sou paj anvan an), lè l sèvi avèk yon kondisyon nan ki kote.
Nan ka sa a, nou kòmanse nan lefèt ke seleksyon yo egzekite sou yon seri òdone (bon ansyen lòd pa). Piske nou gen yon seri òdone, nou ka itilize yon filtè ki senp pou jwenn sèlman done ki dèyè dènye dosye paj anvan an:
SELECT ...
FROM ...
WHERE ...
AND id < ?last_seen_id
ORDER BY id DESC
FETCH FIRST 10 ROWS ONLYSa a tout prensip apwòch sa a. Natirèlman, bagay yo vin pi plis plezi lè klasman pa anpil kolòn, men lide a toujou menm. Li enpòtan sonje ke konsepsyon sa a aplikab pou anpil moun -desizyon.
Yo rele apwòch sa a seek method oswa keyset pagination. Li rezoud pwoblèm nan rezilta k ap flote (nòt: sitiyasyon an ak ekri ant paj li, ki dekri pi bonè) ak, nan kou, sa nou tout renmen, li travay pi vit ak pi estab pase konpanse a klasik. Estabilite manti nan lefèt ke tan an pwosesis demann pa ogmante nan pwopòsyon kantite tab la mande a (nòt: si ou vle aprann plis sou travay la nan apwòch diferan nan pagination, ou ka . Ou ka jwenn tou referans konparatif pou diferan metòd la).
Youn nan glisad yo ke pagination pa kle, nan kou, se pa omnipotent - li gen limit li yo. Ki pi enpòtan an se ke li pa gen kapasite nan li paj o aza (nòt: enkonsistan). Sepandan, nan epòk la nan defile kontinuèl (nòt: sou fen devan an), sa a se pa tankou yon pwoblèm. Espesifye yon nimewo paj pou klike se yon move desizyon nan konsepsyon UI de tout fason (nòt: opinyon otè a nan atik la).
E zouti yo?
Pajaj sou kle souvan pa apwopriye akòz mank de sipò enstrimantal pou metòd sa a. Pifò zouti devlopman, ki gen ladan divès kad, pa pèmèt ou chwazi egzakteman ki jan paginasyon yo pral fèt.
Sitiyasyon an vin pi grav pa lefèt ke metòd ki dekri a mande sipò fen-a-fen nan teknoloji yo itilize - soti nan DBMS a nan ekzekisyon an nan yon demann AJAX nan navigatè a ak defile kontinuèl. Olye pou yo presize jis nimewo paj la, kounye a ou dwe presize yon seri kle pou tout paj an menm tan.
Sepandan, kantite kad ki sipòte paginasyon sou kle ap grandi piti piti. Men sa nou genyen nan moman sa a:
- pou Java;
- pou Ruby;
- и pou Django;
- pou Python;
- â kritè API pou aplikasyon JPA;
- pou Perl;
- , mape pou Node.js .
(Remak: kèk lyen yo te retire akòz lefèt ke nan moman tradiksyon an kèk bibliyotèk pa te mete ajou depi 2017-2018. Si w enterese, ou ka gade sous orijinal la.)
Se nan moman sa a ke èd ou bezwen. Si w devlope oswa sipòte yon kad ki fè nenpòt itilizasyon pajinasyon, Lè sa a, mwen mande, mwen ankouraje, mwen sipliye ou bay sipò natif natal pou paginasyon sou kle yo. Si w gen kesyon oswa si w bezwen èd, m ap kontan ede w (, , ) (nòt: nan eksperyans mwen ak Marcus, mwen ka di ke li vrèman antouzyastik sou gaye sijè sa a).
Si ou itilize solisyon pare yo ke ou panse yo merite pou yo gen sipò pou paginasyon pa kle, kreye yon demann oswa menm ofri yon solisyon pare, si sa posib. Ou kapab tou konekte nan atik sa a.
Konklizyon
Rezon an pou kisa yon apwòch senp ak itil tankou pagination pa kle pa toupatou se pa ke li difisil pou aplike teknikman oswa mande pou nenpòt ki gwo efò. Rezon prensipal ki fè se ke anpil moun yo abitye wè ak travay ak konpanse - se apwòch sa a dikte pa estanda nan tèt li.
Kòm yon rezilta, kèk moun panse sou chanje apwòch la nan paginasyon, e poutèt sa, sipò enstrimantal nan kad ak bibliyotèk ap devlope mal. Se poutèt sa, si lide a ak objektif nan konpanse-gratis paginasyon se pre ou, ede gaye li!
Sous:
Otè: Markus Winand
Sous: www.habr.com
