Epuka kutumia OFFSET na LIMIT katika hoja zenye kurasa

Siku zimepita ambapo haukulazimika kuwa na wasiwasi juu ya kuboresha utendaji wa hifadhidata. Muda hausimami. Kila mjasiriamali mpya wa teknolojia anataka kuunda Facebook inayofuata, huku akijaribu kukusanya data zote anazoweza kuzipata. Biashara zinahitaji data hii ili kutoa mafunzo bora kwa miundo inayowasaidia kupata pesa. Katika hali kama hizi, waandaaji wa programu wanahitaji kuunda API zinazowaruhusu kufanya kazi haraka na kwa uhakika na idadi kubwa ya habari.

Epuka kutumia OFFSET na LIMIT katika hoja zenye kurasa

Iwapo umekuwa ukibuni viambajengo vya programu au hifadhidata kwa urefu wowote wa muda, pengine umeandika msimbo ili kuendesha maswali yaliyo na alama. Kwa mfano, kama hii:

SELECT * FROM table_name LIMIT 10 OFFSET 40

njia ni?

Lakini ikiwa hivi ndivyo ulivyofanya utaftaji wako, samahani kusema kwamba haukufanya kwa njia bora zaidi.

Unataka kunipinga? Unaweza hakuna tumia wakati. Slack, Shopify ΠΈ Mchanganyiko Tayari wanatumia mbinu ninazotaka kuzizungumzia leo.

Taja angalau msanidi programu mmoja ambaye hajawahi kutumia OFFSET ΠΈ LIMIT kufanya maswali ya paginated. Katika MVP (Bidhaa ya Kima cha chini kabisa) na katika miradi ambapo kiasi kidogo cha data kinatumika, mbinu hii inatumika. "Inafanya kazi tu," kwa kusema.

Lakini ikiwa unahitaji kuunda mifumo ya kuaminika na yenye ufanisi tangu mwanzo, unapaswa kutunza mapema kuhusu ufanisi wa kuuliza hifadhidata zinazotumiwa katika mifumo hiyo.

Leo tutazungumza juu ya shida na utekelezwaji wa kawaida (mbaya sana) wa injini za swala zilizo na alama, na jinsi ya kufikia utendaji wa juu wakati wa kutekeleza maswali kama haya.

Je, kuna tatizo gani la OFFSET na LIMIT?

Kama ilivyosemwa tayari, OFFSET ΠΈ LIMIT Wanafanya vizuri katika miradi ambayo haihitaji kufanya kazi na kiasi kikubwa cha data.

Tatizo linatokea wakati hifadhidata inakua kwa saizi ambayo haifai tena kwenye kumbukumbu ya seva. Hata hivyo, unapofanya kazi na hifadhidata hii, unahitaji kutumia maswali ya paginated.

Ili tatizo hili lijitokeze, lazima kuwe na hali ambayo DBMS itatumia operesheni isiyofaa ya Uchanganuzi wa Jedwali Kamili kwenye kila hoja iliyo na ukurasa (wakati uwekaji na ufutaji unaweza kutokea , na hatuhitaji data iliyopitwa na wakati!).

"Uchanganuzi kamili wa jedwali" (au "uchanganuzi wa jedwali mfuatano", Uchanganuzi wa Mfuatano) ni nini? Huu ni operesheni ambayo DBMS husoma kila safu ya jedwali kwa mpangilio, ambayo ni, data iliyomo ndani yake, na inakagua kwa kufuata hali fulani. Aina hii ya uchanganuzi wa jedwali inajulikana kuwa polepole zaidi. Ukweli ni kwamba inapotekelezwa, shughuli nyingi za pembejeo / pato hufanywa ambazo zinahusisha mfumo mdogo wa diski ya seva. Hali hiyo inafanywa kuwa mbaya zaidi na latency inayohusishwa na kufanya kazi na data iliyohifadhiwa kwenye disks, na ukweli kwamba kuhamisha data kutoka kwa diski hadi kumbukumbu ni operesheni kubwa ya rasilimali.

Kwa mfano, una rekodi za watumiaji 100000000 na unaendesha swali na muundo. OFFSET 50000000. Hii inamaanisha kuwa DBMS italazimika kupakia rekodi hizi zote (na hata hatuzihitaji!), Ziweke kwenye kumbukumbu, na baada ya hapo chukua, sema, matokeo 20 yaliyoripotiwa katika LIMIT.

Wacha tuseme inaweza kuonekana kama hii: "chagua safu kutoka 50000 hadi 50020 kutoka 100000". Hiyo ni, mfumo utahitaji kwanza kupakia safu 50000 ili kukamilisha hoja. Unaona ni kazi ngapi isiyo ya lazima ambayo italazimika kufanya?

Ikiwa huniamini, angalia mfano niliounda kwa kutumia vipengele db-fiddle.com

Epuka kutumia OFFSET na LIMIT katika hoja zenye kurasa
Mfano kwenye db-fiddle.com

Huko, upande wa kushoto, kwenye uwanja Schema SQL, kuna nambari inayoingiza safu 100000 kwenye hifadhidata, na kulia, kwenye uwanja. Query SQL, maswali mawili yanaonyeshwa. Ya kwanza, polepole, inaonekana kama hii:

SELECT *
FROM `docs`
LIMIT 10 OFFSET 85000;

Na ya pili, ambayo ni suluhisho bora kwa shida sawa, ni kama hii:

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

Ili kutimiza maombi haya, bonyeza tu kwenye kitufe Run juu ya ukurasa. Baada ya kufanya hivi, tunalinganisha habari kuhusu wakati wa utekelezaji wa hoja. Inabadilika kuwa kutekeleza swali lisilofaa huchukua angalau mara 30 zaidi kuliko kutekeleza la pili (wakati huu hutofautiana kutoka kukimbia hadi kukimbia; kwa mfano, mfumo unaweza kuripoti kwamba swala la kwanza lilichukua 37 ms kukamilika, lakini utekelezaji wa pili - 1 ms).

Na ikiwa kuna data zaidi, basi kila kitu kitaonekana kuwa mbaya zaidi (kuwa na hakika na hii, angalia yangu mfano na safu milioni 10).

Yale ambayo tumezungumza hivi punde yanapaswa kukupa maarifa fulani kuhusu jinsi hoja za hifadhidata huchakatwa.

Tafadhali kumbuka kuwa thamani ya juu OFFSET - muda mrefu ombi litachukua kukamilika.

Nitumie nini badala ya mchanganyiko wa OFFSET na LIMIT?

Badala ya mchanganyiko OFFSET ΠΈ LIMIT Inastahili kutumia muundo uliojengwa kulingana na mpango ufuatao:

SELECT * FROM table_name WHERE id > 10 LIMIT 20

Huu ni utekelezaji wa hoja kwa kutumia upaji wa kielekezi kulingana na kielekezi.

Badala ya kuhifadhi za sasa ndani ya nchi OFFSET ΠΈ LIMIT na kuzisambaza kwa kila ombi, unahitaji kuhifadhi kitufe cha msingi kilichopokelewa (kawaida hii ni ID) na LIMIT, kwa sababu hiyo, maswali sawa na hapo juu yatapatikana.

Kwa nini? Jambo ni kwamba kwa kubainisha kwa uwazi kitambulisho cha safu mlalo ya mwisho iliyosomwa, unaiambia DBMS yako ambapo inahitaji kuanza kutafuta data muhimu. Kwa kuongezea, utaftaji, shukrani kwa utumiaji wa ufunguo, utafanywa kwa ufanisi; mfumo hautalazimika kupotoshwa na mistari nje ya safu maalum.

Wacha tuangalie ulinganisho ufuatao wa utendaji wa maswali anuwai. Hapa kuna swali lisilofaa.

Epuka kutumia OFFSET na LIMIT katika hoja zenye kurasa
Ombi la polepole

Na hapa kuna toleo lililoboreshwa la ombi hili.

Epuka kutumia OFFSET na LIMIT katika hoja zenye kurasa
Ombi la haraka

Hoja zote mbili hurejesha kiasi sawa cha data. Lakini ya kwanza inachukua sekunde 12,80 kukamilisha, na ya pili inachukua sekunde 0,01. Je, unahisi tofauti?

Matatizo ya uwezekano

Ili mbinu ya hoja iliyopendekezwa ifanye kazi kwa ufanisi, jedwali lazima liwe na safu wima (au safu wima) iliyo na faharasa za kipekee, zinazofuatana, kama vile kitambulisho kamili. Katika baadhi ya matukio maalum, hii inaweza kuamua mafanikio ya kutumia maswali hayo ili kuongeza kasi ya kufanya kazi na hifadhidata.

Kwa kawaida, wakati wa kujenga maswali, unahitaji kuzingatia usanifu maalum wa meza na kuchagua taratibu hizo ambazo zitafanya kazi vizuri kwenye meza zilizopo. Kwa mfano, ikiwa unahitaji kufanya kazi katika maswali na idadi kubwa ya data inayohusiana, unaweza kupata kuvutia hii makala.

Ikiwa tunakabiliwa na tatizo la kukosa ufunguo wa msingi, kwa mfano, ikiwa tuna meza yenye uhusiano wa wengi hadi wengi, basi mbinu ya jadi ya kutumia. OFFSET ΠΈ LIMIT, imehakikishiwa kutufaa. Lakini matumizi yake yanaweza kusababisha maswali ya polepole. Katika hali kama hizi, ningependekeza kutumia ufunguo wa msingi wa kuongeza kiotomatiki, hata ikiwa inahitajika tu kushughulikia maswali yaliyo na alama.

Ikiwa una nia ya mada hii - tazama, tazama ΠΈ tazama - vifaa kadhaa muhimu.

Matokeo ya

Hitimisho kuu ambalo tunaweza kuteka ni kwamba, bila kujali ukubwa wa hifadhidata tunayozungumzia, daima ni muhimu kuchambua kasi ya utekelezaji wa swala. Siku hizi, uboreshaji wa suluhisho ni muhimu sana, na ikiwa kila kitu kimeundwa kwa usahihi tangu mwanzo wa kufanya kazi kwenye mfumo fulani, hii, katika siku zijazo, inaweza kuokoa msanidi programu kutoka kwa shida nyingi.

Je, unachambua na kuboresha vipi hoja za hifadhidata?

Epuka kutumia OFFSET na LIMIT katika hoja zenye kurasa

Chanzo: mapenzi.com

Kuongeza maoni