Nima uchun kalitlarda sahifalash uchun instrumental yordam kerak?

Hammaga salom! Men Java + Spring-da mikroservislarni yozuvchi dasturchiman. Men Tinkoff kompaniyasida mahsulot ishlab chiqish bo'yicha ichki guruhlardan birida ishlayman.

Nima uchun kalitlarda sahifalash uchun instrumental yordam kerak?

Bizning jamoamizda ma'lumotlar bazasida so'rovlarni optimallashtirish masalasi ko'pincha paydo bo'ladi. Siz har doim biroz tezroq bo'lishni xohlaysiz, lekin har doim o'ylangan indekslar bilan ishlay olmaysiz - ba'zi vaqtinchalik echimlarni izlashingiz kerak. Ma'lumotlar bazalari bilan ishlashda oqilona optimallashtirishni izlash uchun Internet bo'ylab sayohatlardan birida men topdim Markus Wynandning cheksiz foydali blogi, SQL Performance Explained muallifi. Bu noyob blog turi bo'lib, unda siz ketma-ket barcha maqolalarni o'qishingiz mumkin.

Men siz uchun Markusning qisqacha maqolasini tarjima qilmoqchiman. Buni SQL standarti bo'yicha ofset operatsiyasini bajarishning eski, ammo hali ham dolzarb muammosiga e'tiborni jalb qilishga intiladigan manifest deb atash mumkin.

Ba'zi joylarda men muallifni tushuntirishlar va sharhlar bilan to'ldiraman. Men bunday joylarning barchasiga "taxminan" deb murojaat qilaman. ko'proq aniqlik uchun

Kichik kirish

O'ylaymanki, ko'pchilik ofset orqali sahifa tanlash bilan ishlash qanchalik muammoli va sekin ekanligini biladi. Uni yanada samaraliroq dizayn bilan osongina almashtirish mumkinligini bilarmidingiz?

Shunday qilib, ofset kalit so'zi ma'lumotlar bazasiga so'rovdagi birinchi n ta yozuvni o'tkazib yuborishni aytadi. Biroq, ma'lumotlar bazasi hali ham ushbu birinchi n ta yozuvni diskdan berilgan tartibda o'qishi kerak (eslatma: agar u ko'rsatilgan bo'lsa, tartiblashni qo'llang) va shundan keyingina yozuvlarni n+1 dan boshlab qaytarish mumkin bo'ladi. Eng qizig'i shundaki, muammo DBMSda aniq amalga oshirishda emas, balki standart bo'yicha asl ta'rifda:

…satrlar avval boβ€˜yicha tartiblanadi, soβ€˜ngra boshidan boshlab koβ€˜rsatilgan qatorlar sonini kamaytirish bilan cheklanadi...
-SQL: 2016, 2-qism, 4.15.3 Olingan jadvallar (eslatma: hozirda eng ko'p ishlatiladigan standart)

Bu erda asosiy nuqta shundaki, ofset bitta parametrni oladi - o'tkazib yuboriladigan yozuvlar soni va bu. Ushbu ta'rifdan so'ng, DBMS faqat barcha yozuvlarni olishi va keraksizlarini olib tashlashi mumkin. Shubhasiz, ofsetning bu ta'rifi bizni qo'shimcha ish qilishga majbur qiladi. Va hatto SQL yoki NoSQL bo'lishi muhim emas.

Yana bir oz og'riq

Ofset bilan bog'liq muammolar shu bilan tugamaydi va buning sababi. Agar diskdan ikki varaq ma'lumotni o'qish o'rtasida boshqa operatsiya yangi yozuv kiritsa, bu holda nima bo'ladi?

Nima uchun kalitlarda sahifalash uchun instrumental yordam kerak?

Oldingi sahifalardagi yozuvlarni o'tkazib yuborish uchun ofsetdan foydalanilganda, turli sahifalarni o'qish orasiga yangi yozuv qo'shilgan taqdirda, siz katta ehtimollik bilan dublikatlarga ega bo'lasiz (eslatma: bu biz sahifalarni konstruksiya bo'yicha tartib bilan o'qiganimizda mumkin, keyin chiqishimizning o'rtasida u yangi yozuvni olishi mumkin).

Rasmda bu holat aniq tasvirlangan. Baza dastlabki 10 ta yozuvni o'qiydi, shundan so'ng yangi yozuv kiritiladi, bu esa barcha o'qilgan yozuvlarni 1 ga o'zgartiradi. Keyin baza keyingi 10 ta yozuvdan yangi sahifa oladi va kerak bo'lganidek 11-dan emas, balki 10-dan boshlanadi. XNUMX-o'rin, bu rekordni takrorlash. Ushbu iboradan foydalanish bilan bog'liq boshqa anomaliyalar mavjud, ammo bu eng keng tarqalgan.

Biz allaqachon bilib olganimizdek, bu ma'lum bir ma'lumotlar bazasi yoki ularni amalga oshirish muammolari emas. Muammo SQL standartiga muvofiq sahifalarni aniqlashda. Biz DBMSga qaysi sahifani olish kerakligini yoki qancha yozuvni o'tkazib yuborishni aytamiz. Ma'lumotlar bazasi bunday so'rovni optimallashtirishga qodir emas, chunki buning uchun juda kam ma'lumot mavjud.

Bu aniq kalit so'z bilan emas, balki so'rovning semantikasi bilan bog'liq muammo ekanligini ham aniqlashtirish kerak. Muammoli tabiati bilan bir xil bo'lgan yana bir qancha sintaksislar mavjud:

  • Ofset kalit so'zi yuqorida aytib o'tilganidek.
  • Ikki kalit so'zdan iborat konstruktsiya limiti [ofset] (garchi chegaraning o'zi unchalik yomon emas).
  • Qator raqamlash asosida pastki chegaralar bo'yicha filtrlash (masalan, row_number(), rownum va boshqalar).

Ushbu iboralarning barchasi sizga qancha qatorni o'tkazib yuborishni, qo'shimcha ma'lumot yoki kontekstni ko'rsatmaydi.

Ushbu maqolaning keyingi qismida ofset kalit so'zi ushbu barcha variantlarning xulosasi sifatida ishlatiladi.

OFFSETsiz hayot

Keling, bu muammolarsiz bizning dunyomiz qanday bo'lishini tasavvur qilaylik. Ma'lum bo'lishicha, ofsetsiz hayot unchalik qiyin emas: tanlash bilan siz faqat biz hali ko'rmagan satrlarni (eslatma: ya'ni oldingi sahifada bo'lmaganlarni) qaerda shart yordamida tanlashingiz mumkin.

Bunday holda, biz tanlovlar buyurtma qilingan to'plamda (yaxshi eski tartib tomonidan) amalga oshirilishidan boshlaymiz. Bizda buyurtma qilingan to'plam mavjud bo'lganligi sababli, biz faqat oldingi sahifaning oxirgi yozuvining orqasida joylashgan ma'lumotlarni olish uchun juda oddiy filtrdan foydalanishimiz mumkin:

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

Bu yondashuvning butun printsipi. Albatta, ko'plab ustunlar bo'yicha saralashda narsalar yanada qiziqarli bo'ladi, lekin g'oya hali ham bir xil. Shuni ta'kidlash kerakki, ushbu dizayn ko'pchilik uchun qo'llaniladi NoSQL- qarorlar.

Ushbu yondashuv qidiruv usuli yoki kalitlar to'plamini sahifalash deb ataladi. Bu suzuvchi natija muammosini hal qiladi (eslatma: sahifalar orasidagi yozish bilan bog'liq vaziyat yuqorida tavsiflangan) va, albatta, biz hammamiz yaxshi ko'radigan narsa klassik ofsetga qaraganda tezroq va barqaror ishlaydi. Barqarorlik shundan iboratki, so'rovni ko'rib chiqish vaqti so'ralgan jadval soniga mutanosib ravishda oshmaydi (eslatma: agar siz sahifalashning turli xil yondashuvlari ishi haqida ko'proq bilmoqchi bo'lsangiz, muallifning taqdimotini ko'rib chiqing. Shuningdek, u erda turli usullar uchun qiyosiy ko'rsatkichlarni topishingiz mumkin).

Slaydlardan biri bu haqda gapiradikalitlar bo'yicha sahifalash, albatta, hamma narsaga qodir emas - uning cheklovlari bor. Eng muhimi shundaki, u tasodifiy sahifalarni o'qish qobiliyatiga ega emas (eslatma: nomuvofiq). Biroq, cheksiz aylantirish davrida (eslatma: old tomonda), bu bunday muammo emas. Bosish uchun sahifa raqamini ko'rsatish baribir UI dizaynida noto'g'ri qaror (eslatma: maqola muallifining fikri).

Asboblar haqida nima deyish mumkin?

Ushbu usul uchun instrumental yordam yo'qligi sababli tugmachalardagi sahifalar ko'pincha mos kelmaydi. Ko'pgina ishlab chiqish vositalari, jumladan, turli xil ramkalar, sahifalash qanday amalga oshirilishini aniq tanlashga imkon bermaydi.

Vaziyatni ta'riflangan usul qo'llaniladigan texnologiyalarda - DBMS dan cheksiz aylantirish bilan brauzerda AJAX so'rovini bajarishgacha - oxirigacha qo'llab-quvvatlashni talab qilishi bilan yanada og'irlashadi. Faqat sahifa raqamini ko'rsatish o'rniga, endi siz bir vaqtning o'zida barcha sahifalar uchun kalitlar to'plamini belgilashingiz kerak.

Biroq, kalitlarda sahifalashni qo'llab-quvvatlaydigan ramkalar soni asta-sekin o'sib bormoqda. Hozir bizda nima bor:

(Eslatma: tarjima vaqtida baΚΌzi kutubxonalar 2017-2018-yillardan beri yangilanmagani uchun baΚΌzi havolalar olib tashlandi. Agar qiziqsangiz, asl manbaga qarang.)

Ayni paytda sizning yordamingiz kerak. Agar siz sahifalashdan har qanday foydalanadigan ramka ishlab chiqsangiz yoki qo'llab-quvvatlasangiz, men sizdan kalitlarda sahifalash uchun mahalliy yordam berishingizni so'rayman, iltimos qilaman. Savollaringiz bo'lsa yoki yordam kerak bo'lsa, men yordam berishdan xursand bo'laman (forum, Twitter, aloqa shakli) (eslatma: Markus bilan bo'lgan tajribamdan shuni aytishim mumkinki, u haqiqatan ham ushbu mavzuni tarqatishda ishtiyoqlidir).

Agar siz kalitlar bo'yicha sahifalarni qo'llab-quvvatlashga loyiq deb hisoblagan tayyor echimlardan foydalansangiz, so'rov yarating yoki iloji bo'lsa, tayyor echimni taklif qiling. Shuningdek, ushbu maqolaga havola qilishingiz mumkin.

xulosa

Tugmalar bo'yicha sahifalash kabi oddiy va foydali yondashuv keng tarqalmaganligining sababi uni texnik jihatdan amalga oshirish qiyinligi yoki katta kuch talab qilishi emas. Buning asosiy sababi shundaki, ko'pchilik ofsetni ko'rish va ishlashga odatlangan - bu yondashuv standartning o'zi tomonidan belgilanadi.

Natijada, kam sonli odamlar sahifalash usulini o'zgartirish haqida o'ylashadi va shu sababli ramkalar va kutubxonalarning instrumental yordami yomon rivojlanmoqda. Shuning uchun, agar ofsetsiz sahifalash g'oyasi va maqsadi sizga yaqin bo'lsa, uni tarqatishga yordam bering!

Manba: https://use-the-index-luke.com/no-offset
Muallif: Markus Winand

Manba: www.habr.com

a Izoh qo'shish