Зошто ви е потребна инструментална поддршка за страничење на копчињата?

Здраво на сите! Јас сум заднински развивач кој пишува микросервиси во Java + Spring. Работам во еден од внатрешните тимови за развој на производи во Тинкоф.

Зошто ви е потребна инструментална поддршка за страничење на копчињата?

Во нашиот тим, често се поставува прашањето за оптимизирање на прашања во DBMS. Секогаш сакате да бидете малку побрзи, но не можете секогаш да поминете со смислено конструирани индекси - мора да барате некои решенија. За време на едно од овие талкања низ мрежата во потрага по разумни оптимизации при работа со бази на податоци, најдов Бескрајно корисен блог на Маркус Винанд, автор на SQL Performance Explained. Ова е оној редок тип на блог во кој можете да ги прочитате сите написи по ред.

Би сакал да ви преведам кратка статија од Маркус. Може да се нарече до одреден степен манифест кој се обидува да го привлече вниманието на стариот, но сепак релевантен проблем на извршувањето на операцијата за офсет според SQL стандардот.

На некои места ќе го дополнам авторот со објаснувања и коментари. Ќе ги наречам сите такви места како „приближно“. за поголема јасност

РЌРμР ± РѕР "СЊС € РѕРμ РІРІРμРґРμРЅРёРμ

Мислам дека многу луѓе знаат колку е проблематично и бавно работењето со избирање страници преку офсет. Дали знаевте дека може многу лесно да се замени со поефикасен дизајн?

Значи, офсет клучниот збор и кажува на базата на податоци да ги прескокне првите n записи во барањето. Сепак, базата на податоци сè уште треба да ги чита овие први n записи од дискот, во дадениот редослед (забелешка: примени сортирање ако е наведено), и само тогаш ќе биде можно да се вратат записите од n+1 наваму. Најинтересно е што проблемот не е во специфичната имплементација во DBMS, туку во оригиналната дефиниција според стандардот:

...редниците прво се подредуваат според , а потоа се ограничуваат со отфрлање на бројот на редови наведен во од почетокот...
-SQL:2016, Дел 2, 4.15.3 Изведени табели (забелешка: моментално најкористениот стандард)

Клучната точка овде е дека офсет зема еден параметар - бројот на записи што треба да се прескокнат, и тоа е тоа. Следејќи ја оваа дефиниција, DBMS може само да ги врати сите записи, а потоа да ги отфрли непотребните. Очигледно, оваа дефиниција за офсет не принудува да направиме дополнителна работа. И не е ни важно дали е SQL или NoSQL.

Само уште малку болка

Проблемите со офсет не завршуваат тука, а еве зошто. Ако, помеѓу читањето на две страници со податоци од дискот, друга операција внесе нов запис, што ќе се случи во овој случај?

Зошто ви е потребна инструментална поддршка за страничење на копчињата?

Кога офсет се користи за прескокнување записи од претходните страници, во ситуација на додавање нов запис помеѓу читањата на различни страници, најверојатно ќе добиете дупликати (забелешка: ова е можно кога читаме страница по страница користејќи редослед по конструкција, потоа во средината на нашиот излез може да добие нов запис).

Сликата јасно ја отсликува оваа ситуација. Основата ги чита првите 10 записи, по што се вметнува нов запис, кој ги поместува сите записи за читање за 1. Потоа базата зема нова страница од следните 10 записи и започнува не од 11-та, како што треба, туку од 10-ти, дуплирање на овој рекорд. Постојат и други аномалии поврзани со употребата на овој израз, но ова е најчеста.

Како што веќе дознавме, ова не се проблеми на специфичен DBMS или нивни имплементации. Проблемот е во дефинирањето на страницата според SQL стандардот. Ние му кажуваме на DBMS која страница да преземе или колку записи да прескокне. Базата на податоци едноставно не е во можност да го оптимизира таквото барање, бидејќи има премалку информации за ова.

Исто така, вреди да се разјасни дека ова не е проблем со одреден клучен збор, туку со семантиката на барањето. Има уште неколку синтакси кои се идентични по својата проблематична природа:

  • Клучниот збор за офсет е како што беше споменато претходно.
  • Конструкција од два клучни збора ограничува [офсет] (иако самото ограничување не е толку лошо).
  • Филтрирање по долни граници, врз основа на нумерирање на редови (на пример, row_number(), rownum, итн.).

Сите овие изрази едноставно ви кажуваат колку линии да прескокнете, без дополнителни информации или контекст.

Подоцна во овој напис, клучниот збор офсет се користи како резиме на сите овие опции.

Животот без ОФСЕТ

Сега да замислиме каков би бил нашиот свет без сите овие проблеми. Излегува дека животот без поместување не е толку тежок: со избирање, можете да ги изберете само оние редови што сè уште не сме ги виделе (забелешка: тоа е, оние што не беа на претходната страница), користејќи услов каде.

Во овој случај, тргнуваме од фактот дека селекциите се извршуваат на подредено множество (стар добар редослед од). Бидејќи имаме нарачано множество, можеме да користиме прилично едноставен филтер за да ги добиеме само податоците што се зад последниот запис од претходната страница:

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

Тоа е целиот принцип на овој пристап. Се разбира, работите стануваат позабавни кога се подредуваат по многу колони, но идејата е сепак иста. Важно е да се напомене дека овој дизајн е применлив за многумина NoSQL-одлуки.

Овој пристап се нарекува метод на барање или пагирање на копчињата. Го решава проблемот со лебдечкиот резултат (забелешка: ситуацијата со пишување помеѓу прочитаните страници опишана претходно) и, се разбира, она што сите го сакаме, работи побрзо и постабилно од класичниот офсет. Стабилноста се состои во тоа што времето за обработка на барањата не се зголемува пропорционално со бројот на бараната табела (забелешка: ако сакате да дознаете повеќе за работата на различните пристапи кон пагинирање, можете погледнете ја презентацијата на авторот. Таму можете да најдете и компаративни одредници за различни методи).

Еден од слајдовите зборува за тоадека страницирањето со копчиња, се разбира, не е семоќно - има свои ограничувања. Најзначајно е што таа нема способност да чита случајни страници (забелешка: неконзистентно). Сепак, во ерата на бескрајно лизгање (забелешка: на предниот дел), ова не е таков проблем. Наведувањето број на страница за кликнување е сепак лоша одлука во дизајнот на UI (забелешка: мислење на авторот на статијата).

Што е со алатките?

Пагинирањето на копчињата честопати не е погодно поради недостаток на инструментална поддршка за овој метод. Повеќето развојни алатки, вклучително и различни рамки, не дозволуваат да изберете точно како ќе се врши пагинирањето.

Ситуацијата се влошува со фактот дека опишаниот метод бара поддршка од крај до крај во користените технологии - од DBMS до извршување на барање AJAX во прелистувачот со бескрајно лизгање. Наместо да го одредувате само бројот на страницата, сега треба да наведете збир на копчиња за сите страници одеднаш.

Сепак, бројот на рамки што поддржуваат страници на копчињата постепено расте. Еве што имаме во моментов:

(Забелешка: некои врски беа отстранети поради фактот што во времето на преводот некои библиотеки не беа ажурирани од 2017-2018 година. Доколку ве интересира, можете да го погледнете оригиналниот извор.)

Токму во овој момент е потребна вашата помош. Ако развивате или поддржувате рамка што користи било каква страница од страници, тогаш ве молам, ве повикувам, ве молам да обезбедите домашна поддршка за страници на клучеви. Ако имате прашања или ви треба помош, со задоволство ќе ви помогнам (форум, Twitter, форма за контакт) (забелешка: од моето искуство со Маркус, можам да кажам дека тој е навистина ентузијаст за ширење на оваа тема).

Ако користите готови решенија за кои мислите дека заслужуваат поддршка за пагинирање по копчиња, направете барање или дури понудете готово решение, ако е можно. Можете исто така да се поврзете со оваа статија.

Заклучок

Причината зошто толку едноставен и корисен пристап како што е страницата со копчиња не е широко распространет не е тоа што е тешко да се спроведе технички или бара голем напор. Главната причина е што многумина се навикнати да гледаат и да работат со офсет - овој пристап е диктиран од самиот стандард.

Како резултат на тоа, малку луѓе размислуваат за промена на пристапот кон пагирање, и поради тоа, инструменталната поддршка од рамки и библиотеки слабо се развива. Затоа, доколку ви е блиску идејата и целта за офсет-слободна страница, помогнете да ја раширите!

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

Извор: www.habr.com

Додадете коментар