Ji karanîna OFFSET û LIMIT-ê di pirsên paşînkirî de dûr bixin

Roj derbas bûn ku hûn ne hewce bûn ku hûn ji xweşbînkirina performansa databasê xeman bikin. Dem namîne. Her karsaziyek teknolojiyê ya nû dixwaze Facebook-a paşîn biafirîne, di heman demê de hewl dide ku hemî daneyên ku di destê wan de ye berhev bike. Karsaz ji van daneyan hewce ne ku modelên çêtir perwerde bikin ku ji wan re dibe alîkar ku drav bidin. Di şert û mercên weha de, bernamenûs pêdivî ye ku API-yên ku destûrê dide wan ku zû û pêbawer bi gelek agahdariyan re bixebitin biafirînin.

Ji karanîna OFFSET û LIMIT-ê di pirsên paşînkirî de dûr bixin

Ger we ji bo demek dirêj ve paşnavên serîlêdanê an databasê sêwirandibe, belkî we kod nivîsandiye da ku pirsên paşînkirî bimeşînin. Mînakî, bi vî rengî:

SELECT * FROM table_name LIMIT 10 OFFSET 40

Çawa ew e?

Lê heke we rûpela xwe bi vî rengî kir, ez xemgîn im ku bibêjim ku we ew bi awayê herî bikêr nekiriye.

Ma hûn dixwazin li hember min îtîraz bikin? Hûn dikarin ne xerckirin время. Slack, shopify и Mixmax Ew jixwe teknîkên ku ez dixwazim îro li ser biaxivim bikar tînin.

Bi kêmanî yek pêşdebirek paşverû yê ku qet bikar neaniye nav bike OFFSET и LIMIT ji bo pêkanîna lêpirsînên pagînekirî. Di MVP (Hilbera Berbiçav ya Kêmtirîn) û di projeyên ku mîqdarên piçûk ên daneyê têne bikar anîn de, ev nêzîkatî pir bikêr e. Ew "tenê dixebite", da ku biaxivin.

Lê heke hûn hewce ne ku pergalên pêbawer û bikêrhatî ji sifrê biafirînin, divê hûn berê xwe bidin ser bandoriya lêpirsîna databasên ku di pergalên weha de têne bikar anîn.

Îro em ê li ser pirsgirêkên pêkanînên bi gelemperî têne bikar anîn (pir xirab) motorên lêgerînê yên pagînekirî, û ka meriv çawa di pêkanîna van pirsan de performansa bilind bi dest dixe.

Çi xeletiya OFFSET û LIMIT heye?

Wekî ku berê gotî, OFFSET и LIMIT Ew di projeyên ku ne hewce ne ku bi daneya mezin re bixebitin baş dikin.

Pirsgirêk dema ku databas ewqas mezin dibe ku êdî di bîra serverê de cîh nagire derdikeve holê. Lêbelê, dema ku hûn bi vê databasê re dixebitin, hûn hewce ne ku pirsên paşînkirî bikar bînin.

Ji bo ku ev pirsgirêk xwe diyar bike, pêdivî ye ku rewşek hebe ku tê de DBMS li ser her pirsek pagînekirî serî li xebatek bêbandor Vegerandina Tabloyê bide (dema ku dibe ku operasyonên lêxistin û jêbirinê çêbibin, û em ne hewceyî daneyên kevnar in!).

"Sakandina tabloya tam" (an "paqijkirina sifrê ya li pey hev", Lêgerîna Rêzdar) çi ye? Ev operasyonek e ku di dema DBMS-ê de her rêzek tabloyê, ango daneyên ku tê de hene, bi rêz dixwîne û wan ji bo pêkanîna şertek diyarkirî kontrol dike. Tê zanîn ku ev celeb şopandina sifrê ya herî hêdî ye. Rastî ev e ku dema ku ew tête darve kirin, gelek operasyonên têketin / derketinê têne kirin ku binepergala dîska serverê vedihewîne. Rewş ji hêla derengiya ku bi xebata bi daneyên ku li ser dîskan ve hatî hilanîn ve girêdayî ye xirabtir dibe, û rastiya ku veguheztina daneyan ji dîskê ber bi bîranînê ve xebatek çavkaniyek giran e.

Mînakî, qeydên we yên 100000000 bikarhêneran hene û hûn bi avahîsaziyê pirsek dimeşînin. OFFSET 50000000. Ev tê vê wateyê ku DBMS neçar e ku van hemî tomaran bar bike (û em ne hewceyî wan jî ne!), wan têxe bîranînê, û piştî wê bigire, bêje, 20 encam di nav de hatine ragihandin. LIMIT.

Em bibêjin ku dibe ku bi vî rengî xuya bike: "Rêzan ji 50000 heta 50020 ji 100000 hilbijêrin". Ango, pergal dê pêşî hewce bike ku 50000 rêzan bar bike da ku pirsê temam bike. Ma hûn dibînin ku ew ê çiqas karên nehewce bike?

Heke hûn ji min bawer nakin, li mînaka ku min bi karanîna taybetmendiyan afirandiye binêre db-fiddle.com

Ji karanîna OFFSET û LIMIT-ê di pirsên paşînkirî de dûr bixin
Mînak li db-fiddle.com

Li wir, li çepê, li zeviyê Schema SQL, kodek heye ku 100000 rêzan dixe nav databasê, û li milê rastê, li qadê Query SQL, du pirs têne xuyang kirin. Ya yekem, hêdî, bi vî rengî xuya dike:

SELECT *
FROM `docs`
LIMIT 10 OFFSET 85000;

Û ya duyemîn, ku ji bo heman pirsgirêkê çareseriyek bi bandor e, wiha ye:

SELECT *
FROM `docs`
WHERE id > 85000
LIMIT 10;

Ji bo bicihanîna van daxwazan, tenê li ser bişkojkê bikirtînin Run li serê rûpelê. Piştî vê yekê, em agahdariya di derbarê dema darvekirina pirsê de berhev dikin. Derdikeve holê ku pêkanîna pirsek bêbandor herî kêm 30 carî ji pêkanîna ya duyemîn dirêjtir digire (vê car ji xebitandinê heya xebitandinê diguhere; mînakî, dibe ku pergal rapor bike ku pirsa yekem 37 ms girtiye ku temam bibe, lê pêkanîna duyemîn - 1 ms).

Û heke bêtir dane hebin, wê hingê dê her tişt hîn xirabtir xuya bike (ji bo ku hûn ji vê yekê bawer bin, li min binêrin nimûne bi 10 mîlyon rêzan).

Tiştê ku me nû bahs kir divê hindek têgihiştinê bide we ka pirsên databasê bi rastî çawa têne hilberandin.

Ji kerema xwe not bikin ku nirx bilindtir e OFFSET - Dê daxwazname çiqas dirêj bidome.

Divê ez li şûna berhevoka OFFSET û LIMIT çi bikar bînim?

Li şûna hevgirtinê OFFSET и LIMIT Hêja ye ku avahiyek ku li gorî nexşeya jêrîn hatî çêkirin bikar bînin:

SELECT * FROM table_name WHERE id > 10 LIMIT 20

Ev înfazkirina pirsê ye bi pagasyonek li gorî kursorê.

Li şûna ku yên heyî li herêmî hilînin OFFSET и LIMIT û bi her daxwazê ​​re wan veguhezînin, hûn hewce ne ku mifteya bingehîn a paşîn a wergirtinê hilînin (bi gelemperî ev e ID) û LIMIT, di encamê de, pirsên mîna yên jorîn dê bêne wergirtin.

Çima? Mesele ev e ku bi eşkere danasîna nasnameya rêza paşîn a xwendinê, hûn ji DBMS-a xwe re dibêjin ku ew li ku derê hewce dike ku dest bi lêgerîna daneyên pêwîst bike. Digel vê yekê, lêgerîn, bi saya karanîna mifteyê, dê bi rengek bikêrhatî were meşandin.

Ka em li berhevdana performansa jêrîn a pirsên cihêreng binêrin. Li vir pirsek bêbandor heye.

Ji karanîna OFFSET û LIMIT-ê di pirsên paşînkirî de dûr bixin
Daxwaza hêdî

Û li vir guhertoyek xweşbînkirî ya vê daxwazê ​​ye.

Ji karanîna OFFSET û LIMIT-ê di pirsên paşînkirî de dûr bixin
Daxwaza bilez

Her du pirs bi tevahî heman daneyê vedigerin. Lê ya yekem 12,80 çirkeyan digire, ya duyemîn jî 0,01 çirkeyan digire. Ma hûn cûdahiyê hîs dikin?

Pirsgirêkên pêkanîn

Ji bo ku rêbaza pirsê ya pêşniyarkirî bi bandor bixebite, pêdivî ye ku tablo xwedan stûnek (an stûnek) be ku tê de navnîşên yekta, rêzdar, mîna nasnameyek jimareyek tevde, hebe. Di hin rewşên taybetî de, ev dibe ku serkeftina karanîna pirsên weha diyar bike ku leza xebata bi databasê re zêde bike.

Bi xwezayî, dema çêkirina pirsan, hûn hewce ne ku mîmariya taybetî ya tabloyan bihesibînin û wan mekanîzmayên ku dê li ser tabloyên heyî çêtirîn bixebitin hilbijêrin. Mînakî, heke hûn hewce ne ku di pirsnameyên bi cildên mezin ên daneyên têkildar de bixebitin, dibe ku hûn wê balkêş bibînin ev tişt.

Ger em bi pirsgirêka windakirina mifteyek bingehîn re rû bi rû bimînin, mînakî, heke me tabloyek bi têkiliyek pir-bi-gelek heye, wê hingê nêzîkatiya kevneşopî ya karanîna OFFSET и LIMIT, garantî ye ku li gorî me. Lê karanîna wê dibe ku bibe sedema pirsên potansiyel hêdî. Di rewşên weha de, ez ê pêşniyar bikim ku mifteyek seretayî ya xweser-zêdebûyî bikar bînin, hetta ku ew tenê ji bo birêvebirina pirsên paşînkirî hewce be.

Heke hûn bi vê mijarê re eleqedar dibin - Va ye, Va ye и Va ye - gelek materyalên kêrhatî.

Encam

Encama sereke ya ku em dikarin derxînin ev e ku, çi mezinahiya databasên ku em li ser diaxivin, her gav hewce ye ku leza pêkanîna pirsê were analîz kirin. Naha, mezinbûna çareseriyan pir girîng e, û heke her tişt ji destpêka xebata li ser pergalek diyarkirî ve rast were sêwirandin, ev, di pêşerojê de, dikare pêşdebir ji gelek pirsgirêkan xilas bike.

Meriv çawa pirsên databasê analîz dike û xweşbîn dike?

Ji karanîna OFFSET û LIMIT-ê di pirsên paşînkirî de dûr bixin

Source: www.habr.com

Add a comment