Неліктен пернелердегі беттеу үшін аспаптық қолдау қажет?

Бәріңе сәлем! Мен Java + Spring бағдарламасында микросервистерді жазатын бэкенд әзірлеушісімін. Мен Tinkoff компаниясында ішкі өнімді әзірлеу топтарының бірінде жұмыс істеймін.

Неліктен пернелердегі беттеу үшін аспаптық қолдау қажет?

Біздің командада ДҚБЖ-дағы сұраныстарды оңтайландыру мәселесі жиі туындайды. Сіз әрқашан сәл жылдамырақ болғыңыз келеді, бірақ мұқият құрастырылған индекстермен әрқашан қол жеткізе алмайсыз - кейбір уақытша шешімдер іздеу керек. Дерекқорлармен жұмыс істеу кезінде ақылға қонымды оңтайландыруларды іздеу үшін Интернетті шарлаудың бірінде мен таптым Маркус Уайнандтың шексіз пайдалы блогы, SQL Performance Explained авторы. Бұл барлық мақалаларды қатарынан оқи алатын сирек кездесетін блог түрі.

Мен сізге Маркустың қысқаша мақаласын аударғым келеді. Оны белгілі бір дәрежеде SQL стандарты бойынша офсеттік операцияны орындаудың ескі, бірақ әлі де өзекті мәселесіне назар аударуға тырысатын манифест деп атауға болады.

Кей жерлерде авторды түсініктемелермен және түсініктемелермен толықтырамын. Мен мұндай орындардың барлығын «шамамен» деп атаймын. көбірек түсінікті болу үшін

Кішігірім кіріспе

Менің ойымша, көптеген адамдар офсет арқылы бет таңдауымен жұмыс істеу қаншалықты қиын және баяу екенін біледі. Оны тиімдірек дизайнмен оңай ауыстыруға болатынын білесіз бе?

Сонымен, офсет кілт сөзі дерекқорға сұраудағы бірінші n жазбаны өткізіп жіберуді айтады. Дегенмен, дерекқор әлі де дискіден осы бірінші n жазбаны берілген ретпен оқуы керек (ескерту: егер ол көрсетілген болса, сұрыптауды қолданыңыз), содан кейін ғана n+1 бастап жазбаларды қайтару мүмкін болады. Ең қызығы, мәселе ДҚБЖ-да нақты іске асыруда емес, стандартқа сәйкес бастапқы анықтамада:

…жолдар алдымен бойынша сұрыпталады, содан кейін басынан бастап көрсетілген жолдар санын азайту арқылы шектеледі…
-SQL:2016, 2-бөлім, 4.15.3 Туынды кестелер (ескерту: қазіргі уақытта ең көп қолданылатын стандарт)

Мұндағы негізгі мәселе, офсет бір параметрді қабылдайды - өткізіп жіберуге болатын жазбалар саны, және бұл. Осы анықтамадан кейін ДҚБЖ тек барлық жазбаларды шығарып, қажетсіздерін алып тастай алады. Офсеттің бұл анықтамасы бізді қосымша жұмыс жасауға мәжбүр ететіні анық. Оның SQL немесе NoSQL екендігі маңызды емес.

Тек аздап ауырады

Офсеттік мәселелер мұнымен бітпейді, сондықтан да осында. Егер дискіден екі беттік деректерді оқу арасында басқа операция жаңа жазбаны енгізсе, бұл жағдайда не болады?

Неліктен пернелердегі беттеу үшін аспаптық қолдау қажет?

Алдыңғы беттердегі жазбаларды өткізіп жіберу үшін офсетті пайдаланған кезде, әртүрлі беттерді оқу арасында жаңа жазбаны қосу жағдайында, сіз қайталанулар алуыңыз мүмкін (ескерту: бұл құрылым бойынша ретті пайдаланып бетті бет оқығанда мүмкін, содан кейін біздің шығарылымның ортасында ол жаңа жазба алуы мүмкін).

Суретте бұл жағдай анық көрсетілген. База алғашқы 10 жазбаны оқиды, содан кейін жаңа жазба енгізіледі, ол барлық оқылған жазбаларды 1-ге ауыстырады. Содан кейін база келесі 10 жазбадан жаңа бетті алады және қажет болғандай 11-ден емес, 10-ден басталады. XNUMX-шы, осы рекордты қайталау. Бұл өрнекті қолдануға байланысты басқа ауытқулар бар, бірақ бұл ең көп таралған.

Біз бұрыннан белгілі болғандай, бұл нақты ДҚБЖ немесе оларды іске асыру мәселелері емес. Мәселе SQL стандартына сәйкес беттеуді анықтауда. Біз ДҚБЖ қай бетті алу керектігін немесе қанша жазбаны өткізіп жіберу керектігін айтамыз. Деректер базасы мұндай сұрауды оңтайландыра алмайды, өйткені бұл үшін ақпарат тым аз.

Сондай-ақ, бұл нақты кілт сөзге қатысты мәселе емес, сұраудың семантикасына қатысты мәселе екенін түсіндірген жөн. Проблемалық табиғаты бойынша бірдей тағы бірнеше синтаксис бар:

  • Офсеттік кілт сөзі бұрын айтылғандай.
  • Limit [offset] екі кілт сөзінің құрылысы (бірақ шектеудің өзі соншалықты жаман емес).
  • Жол нөмірлеуіне негізделген төменгі шекаралар бойынша сүзу (мысалы, жол_саны(), қатар, т.б.).

Бұл өрнектердің барлығы сізге қанша жолды өткізіп жіберу керектігін, қосымша ақпарат немесе контекст жоқ екенін көрсетеді.

Кейінірек осы мақалада офсет кілт сөзі барлық осы опциялардың қысқаша мазмұны ретінде пайдаланылады.

ОФСЕТсіз өмір

Енді осы проблемаларсыз біздің әлем қандай болатынын елестетіп көрейік. Офсетсіз өмір соншалықты қиын емес екені белгілі болды: таңдау арқылы біз әлі көрмеген жолдарды (ескерту: яғни алдыңғы бетте болмаған жолдарды) қай жердегі шартты қолдана отырып таңдауға болады.

Бұл жағдайда таңдаулар реттелген жиынтықта орындалатындығынан бастаймыз (жақсы ескі тәртіп бойынша). Бізде реттелген жиын болғандықтан, біз алдыңғы беттің соңғы жазбасының артындағы деректерді ғана алу үшін өте қарапайым сүзгіні пайдалана аламыз:

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

Бұл тәсілдің бүкіл принципі. Әрине, көптеген бағандар бойынша сұрыптау кезінде нәрселер қызықтырақ болады, бірақ идея әлі де бірдей. Бұл дизайн көптеген адамдарға жарамды екенін ескеру маңызды NoSQL-шешімдер.

Бұл тәсіл іздеу әдісі немесе кілттер жиынын беттеу деп аталады. Ол өзгермелі нәтиже мәселесін шешеді (ескертпе: бет оқулары арасында бұрын сипатталған жазу жағдайы) және, әрине, бәрімізге ұнайтын нәрсе, ол классикалық офсетке қарағанда тезірек және тұрақты жұмыс істейді. Тұрақтылық сұранысты өңдеу уақыты сұралған кестенің санына пропорционалды өспейтіндігінде жатыр (ескерту: егер сіз беттеудің әртүрлі тәсілдерінің жұмысы туралы көбірек білгіңіз келсе, сіз автордың презентациясын қараңыз. Әртүрлі әдістер үшін салыстырмалы көрсеткіштерді де сол жерден таба аласыз).

Слайдтардың бірі бұл туралы айтадыбұл пернелер арқылы беттеу, әрине, құдіретті емес - оның шектеулері бар. Ең бастысы, оның кездейсоқ беттерді оқу мүмкіндігі жоқ (ескерту: сәйкес емес). Дегенмен, шексіз айналдыру дәуірінде (ескерту: алдыңғы жағында) бұл мәселе емес. Басу үшін бет нөмірін көрсету бәрібір UI дизайнында дұрыс емес шешім (ескерту: мақала авторының пікірі).

Құралдар ше?

Бұл әдісті аспаптық қолдаудың болмауына байланысты пернелердегі беттеу жиі қолайлы емес. Көптеген әзірлеу құралдары, соның ішінде әртүрлі фреймворктар беттеуді дәл қалай орындайтынын таңдауға мүмкіндік бермейді.

Сипатталған әдіс қолданылатын технологияларда - ДҚБЖ-дан бастап шексіз айналдыру арқылы браузерде AJAX сұрауын орындауға дейін үздіксіз қолдауды қажет ететіндігі жағдайды қиындатады. Тек бет нөмірін көрсетудің орнына енді барлық беттер үшін кілттер жинағын бірден көрсету керек.

Дегенмен, кілттердегі беттеуді қолдайтын фреймворктардың саны біртіндеп өсіп келеді. Міне, қазір бізде:

(Ескерту: аударма кезінде кейбір кітапханалар 2017-2018 жылдардан бері жаңартылмағандықтан кейбір сілтемелер жойылды. Егер сізді қызықтырса, түпнұсқа дереккөзді қарауға болады.)

Дәл осы сәтте сіздің көмегіңіз қажет болып тұр. Егер сіз беттеуді кез келген пайдаланатын құрылымды дамытатын болсаңыз немесе қолдайтын болсаңыз, онда мен сізден пернелердегі беттеу үшін жергілікті қолдау көрсетуіңізді сұраймын, өтінемін. Сұрақтарыңыз болса немесе көмек қажет болса, мен көмектесуге қуаныштымын (форум, Twitter, байланыс формасы) (ескерту: Маркуспен болған тәжірибемнен оның бұл тақырыпты таратуға шын ынтасымен қарайтынын айта аламын).

Егер сіз пернелер арқылы беттеуді қолдауға лайық деп ойлайтын дайын шешімдерді пайдалансаңыз, мүмкін болса, сұрау жасаңыз немесе тіпті дайын шешімді ұсыныңыз. Сіз сондай-ақ осы мақалаға сілтеме жасай аласыз.

қорытынды

Кілттер арқылы беттеу сияқты қарапайым және пайдалы тәсілдің кең таралмағанының себебі, оны техникалық түрде жүзеге асыру қиын немесе көп күш жұмсау қажет емес. Басты себебі, көбісі офсетпен көруге және жұмыс істеуге дағдыланған - бұл тәсіл стандарттың өзі белгілейді.

Нәтижесінде беттеу әдісін өзгерту туралы аз адамдар ойлайды, сондықтан фреймворктер мен кітапханалардан құралдық қолдау нашар дамып келеді. Сондықтан, офсетсіз беттеу идеясы мен мақсаты сізге жақын болса, оны таратуға көмектесіңіз!

Ақпарат көзі: https://use-the-index-luke.com/no-offset
Авторы: Маркус Винд

Ақпарат көзі: www.habr.com

пікір қалдыру