MySQL LIMIT & OFFSET с примери

⚡ Умно обобщение

- MySQL Ключовата дума LIMIT ограничава броя на редовете, които връща заявката, а стойността OFFSET определя от кой ред започва резултатът. Заедно те поддържат наборите от резултати малки, правят страниците да се зареждат бързо и задвижват пагинация запис по запис.

  • 🔢 Основно поведение: LIMIT N връща най-много N реда. Таблица, съдържаща по-малко редове от N, връща всички редове без грешка.
  • 0️⃣ Нулев случай: LIMIT 0 не връща никакви редове, което го прави евтин начин за проверка на метаданните на колоните.
  • 📍 Синтаксис на отместване: LIMIT 1, 2 пропуска един ред и връща два, така че отместването се записва първо, а броят на редовете - второ.
  • 📄 Формула за пагинация: OFFSET е равно на размера на страницата, умножен по номера на страницата минус едно, което превръща резултата в номерирани страници.
  • ↕️ Зависимост от поръчката: Без ORDER BY, MySQL може да върне различни редове при всяко изпълнение, така че LIMIT е детерминистичен само с изрично сортиране.
  • Поддръжка на изявление: LIMIT също така ограничава редовете, засегнати от UPDATE и DELETE, предпазвайки голяма таблица от неограничен запис.
  • ???? Предупреждение за производителност: Голямо отместване прави MySQL чете и изхвърля всеки пропуснат ред, така че дълбоките страници растат по-бавно.

MySQL ЛИМИТ и ОТМЕСТВАНЕ

Каква е ключовата дума LIMIT в MySQL?

- ОГРАНИЧАВА Ключовата дума ограничава броя на редовете, върнати в резултат от заявка. Може да се използва с операторите SELECT, UPDATE и DELETE, така че ограничава редовете, които заявката чете, както и редовете, които записът засяга.

Синтаксисът на ключовата дума LIMIT е следният.

SELECT {fieldname(s) | *} FROM tableName(s) [WHERE condition] LIMIT N;

ТУК

  • „ИЗБЕРЕТЕ {име на поле(а) | *} FROM tableName(s)” е SELECT израз съдържащи полетата, които бихме искали да върнем в нашата заявка.
  • „[WHERE условие]“ е незадължителен, но когато е предоставен, той определя филтър върху резултатния набор. WHERE клауза се прилага преди LIMIT, така че филтрирането се извършва първо и ограничението се прилага към това, което оцелява.
  • „ЛИМИТ N“ е ключовата дума и N е всяко число, започващо от 0. Поставянето на 0 като ограничение не връща никакви записи. Поставянето на число като 5 връща пет записа. Ако таблицата съдържа по-малко записи от N, всички те се връщат и не се генерира грешка.

Синтаксисът е кратък, но причината за съществуването му си струва да се посочи преди примерите.

Защо трябва да използваме ключовата дума LIMIT?

Да предположим, че се развивамеping приложението, което работи върху myflixdb. Системните дизайнери ни помолиха да ограничим броя на записите, показвани на страница, до 20 записа, за да се противодейства на бавното зареждане. Как да внедрим система, която отговаря на такова изискване?

Ключовата дума LIMIT обработва точно тази ситуация. Вместо да изтегля всеки ред член в приложението и да отхвърля повечето от тях, заявката връща 20 записа на страница и базата данни върши работата. От това следват три предимства.

  • По-бърз отговор: по-малко данни се четат от диска и по-малко данни преминават през мрежата.
  • По-ниско използване на паметта: приложението съдържа една страница с редове, а не цялата таблица.
  • Сейфър пише: ОГРАНИЧЕНИЕ на АКТУАЛИЗАЦИЯ или ИЗТРИЙ Изразът ограничава броя на редовете, които една грешка може да докосне.

MySQL Примери за заявки LIMIT

Примерите по-долу се изпълняват спрямо таблицата members на базата данни myflixdb. Първият връща два реда и нищо повече.

SELECT * FROM members LIMIT 2;
членски_ номер пълни_ имена пол дата_на_раждане дата_на_регистрация физически_ адрес пощенски_ адрес номер за контакт електронна поща номер на кредитна_карта
1 Джанет Джоунс Женски 21-07-1980 NULL Първа улица Парцел №4 Лична чанта 0759 253 542 janetjones@yagoo.cm NULL
2 Джанет Смит Джоунс Женски 23-06-1980 NULL Мелроуз 123 NULL NULL jj@fstreet.com NULL

Както показва резултатът по-горе, върнати са само двама членове.

Получаване на списък с десет (10) членове от базата данни

Да предположим, че искаме списък с първите 10 регистрирани членове от базата данни на Myflix. Скриптът по-долу ги пита.

SELECT * FROM members LIMIT 10;

Изпълнението на скрипта дава резултата, показан по-долу.

членски_ номер пълни_ имена пол дата_на_раждане дата_на_регистрация физически_ адрес пощенски_ адрес номер за контакт електронна поща номер на кредитна_карта
1 Джанет Джоунс Женски 21-07-1980 NULL Първа улица Парцел №4 Лична чанта 0759 253 542 janetjones@yagoo.cm NULL
2 Джанет Смит Джоунс Женски 23-06-1980 NULL Мелроуз 123 NULL NULL jj@fstreet.com NULL
3 Робърт Фил Мъжки 12-07-1989 NULL 3-та улица 34 NULL 12345 rm@tstreet.com NULL
4 Глория Уилямс Женски 14-02-1984 NULL 2-ра улица 23 NULL NULL NULL NULL
5 Леонард Хофщадтер Мъжки NULL NULL Уудкрест NULL 845738767 NULL NULL
6 Шелдън Купър Мъжки NULL NULL Уудкрест NULL 976736763 NULL NULL
7 Раджеш Кутрапали Мъжки NULL NULL Уудкрест NULL 938867763 NULL NULL
8 Лесли Уинкъл Мъжки 14-02-1984 NULL Уудкрест NULL 987636553 NULL NULL
9 Хауърд Воловиц Мъжки 24-08-1981 NULL Южен парк PO Box 4563 987786553 lwolowitz[at]email.me NULL

Върнати са само 9 члена, защото N в клаузата LIMIT е по-голямо от броя на записите в таблицата. Изричното запитване за 9 реда води до същия набор от резултати.

SELECT * FROM members LIMIT 9;

💡 Съвет: LIMIT избира редове от какъвто и да е ред, който сървърът генерира. Добавете ПОДРЕДЕНИ ПО клауза, когато идентичността на редовете е от значение, в противен случай „първите 10 члена“ не е гарантирано да означават едни и същи девет души два пъти.

Ограничаването на броя на редовете е първата половина на функцията. Изборът на място, където да започва прозорецът, е втората.

Използване на стойността OFFSET в заявката LIMIT

- ИЗМЕСТВАНЕ Аргументът „value“ най-често се използва заедно с ключовата дума LIMIT. Той указва от кой ред сървърът започва да извлича данни, така че редовете преди тази точка се пропускат.

Да предположим, че искаме ограничен брой членове, започвайки от средата на таблицата. Скриптът по-долу започва от втория ред и ограничава резултата до два записа.

SELECT * FROM `members` LIMIT 1, 2;

Изпълнението му в MySQL Workbench спрямо myflixdb дава следния резултат.

членски_ номер пълни_ имена пол дата_на_раждане дата_на_регистрация физически_ адрес пощенски_ адрес номер за контакт електронна поща номер на кредитна_карта
2 Джанет Смит Джоунс Женски 23-06-1980 NULL Мелроуз 123 NULL NULL jj@fstreet.com NULL
3 Робърт Фил Мъжки 12-07-1989 NULL 3-та улица 34 NULL 12345 rm@tstreet.com NULL

Обърнете внимание, че тук ОТМЕСТВАНЕ = 1, следователно ред #2 е първият върнат ред и ЛИМИТ = 2, следователно се връщат само 2 записа.

В двуаргументната форма отместването се записва първо, а броят на редовете - второ, което е лесно да се обърне случайно. MySQL също приема изрична форма, която премахва неяснотата и е тази, която се предпочита в новия код.

SELECT * FROM `members` LIMIT 2 OFFSET 1;

И двата оператора връщат едни и същи два реда. След като се разбере отместването, шаблонът за номериране, на който се основава всеки екран със списък, директно се отклонява от него.

Как да се странират резултатите от заявките с LIMIT и OFFSET

Страничното разделяне разделя голям набор от резултати на номерирани страници, а LIMIT, заедно с OFFSET, е механизмът, който го прави. Две стойности управляват всяка заявка за страница: размерът на страницата, който показва колко записа се показват на един екран, и номерът на страницата, поискан от потребителя.

Отместването се извлича от тях с една единствена формула.

-- OFFSET = page_size * (page_number - 1)
SELECT membership_number, full_names
FROM members
ORDER BY membership_number ASC
LIMIT 20 OFFSET 0;   -- page 1

Страница 2 запазва същото ограничение и премества отместването напред с един размер на страницата.

SELECT membership_number, full_names
FROM members
ORDER BY membership_number ASC
LIMIT 20 OFFSET 20;  -- page 2

Три правила поддържат номерирането на страници правилно и бързо.

  1. Винаги сортирайте: Странираната заявка без ORDER BY може да покаже един и същ запис на две различни страници и да скрие напълно друга, защото сървърът е свободен да променя реда на редовете между извикванията.
  2. Сортиране по уникална колона: Връзките в колоната за сортиране оставят реда на свързаните редове неопределен. Сортирането по първичен ключ или добавянето му като средство за прекъсване на връзката премахва проблема.
  3. Гледайте дълбоки страници: ОТМЕСТВАНЕ 100000 сили MySQL да прочете сто хиляди реда и да ги изхвърли, преди да върне следващите двадесет. Времето за отговор нараства с броя на страницата.

За много дълбоко номериране, номерирането на ключове избягва изцяло отместването. Вместо да брои редовете, които ще бъдат пропуснати, заявката запомня последния ключ от предишната страница и пита за редовете след него.

SELECT membership_number, full_names
FROM members
WHERE membership_number > 20      -- last id from the previous page
ORDER BY membership_number ASC
LIMIT 20;

Тази форма остава бърза на всяка дълбочина, защото индексът прескача директно към началния ключ, вместо да обхожда редовете пред него. Компромисът е, че страниците трябва да се обхождат последователно, така че скокping директното преминаване към страница 500 вече не е възможно.

ЛИМИТ в MySQL срещу TOP и FETCH FIRST

LIMIT не е част от всеки SQL диалект, което е важно, щом заявката трябва да се премества между бази данни. MySQL, PostgreSQL, и SQLite споделят ключовата дума LIMIT. SQL Server използва TOP и Oracle използва стандартната клауза FETCH FIRST. Таблицата по-долу сравнява трите.

Клауза Двигател Пример Пропуска редове
ГРАНИЦА … ОТМЕСТВАНЕ MySQL, PostgreSQL, SQLite ИЗБЕРИ * ОТ членове ЛИМИТ 20 ОТМЕСТВАНЕ 40; Да, с OFFSET
TOP SQL Server ИЗБЕРЕТЕ ТОП 20 * ОТ членове; Не, изисква се OFFSET … FETCH
ИЗВЛЕЧИ ПЪРВО Oracle, Db2, стандартен SQL ИЗБЕРИ * ОТ членове ИЗВЛИЧИ САМО ПЪРВИТЕ 20 РЕДОВЕ; Да, с ОТМЕСТВАНЕ … РЕДОВЕ

Поведението е едно и също във всеки случай: ограничаване на броя на редовете и, по избор, пропускане на определен брой редове първо. Променя се само правописът. Заявка, която трябва да се изпълнява на повече от една програма, следователно трябва да изолира клаузата за ограничаване на редовете, вместо да я разпръсква из кодовата база.

Въпроси и Отговори

Да. И двата приемат обикновен брой редове, като например ИЗТРИЙ FROM членове LIMIT 10. Формата за отместване с два аргумента не е разрешена там, така че може да се ограничи само броят на засегнатите редове.

Отместването започва от нула, така че OFFSET 0 започва от първия ред, а OFFSET 1 започва от втория. Самият брой редове е обикновено количество и се чете като нормално число.

Изпълнете отделна SELECT COUNT(*) със същата клауза WHERE, но без LIMIT. Броят показва на приложението колко страници съществуват, докато ограничената заявка връща редовете за текущата страница.

Често, да. Асистенти с изкуствен интелект в клиенти като например MySQL Workbench Пренапишете заявка OFFSET в клауза WHERE на последния видян ключ. Уверете се, че колоната за сортиране е уникална и индексирана, преди да се доверите на пренаписването.

Тъй като генерираният оператор обикновено пропуска ORDER BY. Без изрично сортиране, MySQL може да върне редовете в произволен ред, така че един и същ LIMIT може да генерира различна извадка при всяко изпълнение. Добавете сортирането сами.

Обобщете тази публикация с: