MySQL LIMIT & OFFSET med eksempler
⚡ Smart opsummering
MySQL Nøgleordet LIMIT begrænser, hvor mange rækker en forespørgsel returnerer, og OFFSET-værdien bestemmer, hvilken række resultatet starter fra. Sammen holder de resultatsættene små, får sider til at indlæses hurtigt og driver paginering post-for-post.
Hvad er LIMIT-nøgleordet i MySQL?
GRÆNSE Nøgleordet begrænser antallet af rækker, der returneres i et forespørgselsresultat. Det kan bruges med SELECT-, UPDATE- og DELETE-sætningerne, så det begrænser antallet af rækker, som en forespørgsel læser, samt antallet af rækker, som en skrivning påvirker.
Syntaksen for LIMIT-nøgleordet er som følger.
SELECT {fieldname(s) | *} FROM tableName(s) [WHERE condition] LIMIT N;
HER
- "VÆLG {feltnavn(e) | *} FRA tabelnavn(e)" er SELECT erklæring indeholdende de felter, som vi gerne vil returnere i vores forespørgsel.
- "[WHERE-tilstand]" er valgfrit, men når det angives, angiver det et filter på resultatsættet. WHERE-klausul anvendes før LIMIT, så filtrering sker først, og grænsen anvendes på det, der overlever.
- "GRÆNSE N" er nøgleordet, og N er et hvilket som helst tal startende fra 0. Hvis 0 sættes som grænse, returneres der slet ingen poster. Hvis et tal som 5 sættes, returneres fem poster. Hvis tabellen indeholder færre poster end N, returneres alle, og der opstår ingen fejl.
Syntaksen er kort, men årsagen til dens eksistens er værd at nævne før eksemplerne.
Hvorfor skal vi bruge LIMIT-nøgleordet?
Antag, at vi er udvikledeping den applikation, der kører oven på myflixdb. Systemdesignerne har bedt os om at begrænse antallet af poster, der vises på en side, til 20 poster for at modvirke langsomme indlæsningstider. Hvordan implementerer vi et system, der opfylder et sådant krav?
Nøgleordet LIMIT håndterer præcis denne situation. I stedet for at trække alle medlemsrækker ind i applikationen og kassere de fleste af dem, returnerer forespørgslen 20 poster pr. side, og databasen klarer arbejdet. Der følger tre fordele af det.
- Hurtigere svar: mindre data læses fra disken, og mindre data krydser netværket.
- Lavere hukommelsesforbrug: Applikationen indeholder én side med rækker, ikke hele tabellen.
- Sikrere skriver: en GRÆNSE på en OPDATERING eller en SLET Sætningen begrænser, hvor mange rækker en fejl må berøre.
MySQL LIMIT-forespørgselseksempler
Eksemplerne nedenfor kører mod medlemstabellen i myflixdb-databasen. Det første returnerer to rækker og intet mere.
SELECT * FROM members LIMIT 2;
| medlemsnummer | fulde_ navne | køn | fødselsdato | registreringsdato | fysisk adresse | postadresse | kontaktnummer | kreditkortnummer | |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Janet Jones | Kvinde | 21-07-1980 | NULL | First Street Plot nr. 4 | Privat taske | +0759 253 542 | janetjones@yagoo.cm | NULL |
| 2 | Janet Smith Jones | Kvinde | 23-06-1980 | NULL | Melrose 123 | NULL | NULL | jj@fstreet.com | NULL |
Som resultatet ovenfor viser, er kun to medlemmer blevet returneret.
Hentning af en liste med ti (10) medlemmer fra databasen
Antag, at vi ønsker en liste over de første 10 registrerede medlemmer fra Myflix-databasen. Scriptet nedenfor spørger efter dem.
SELECT * FROM members LIMIT 10;
Udførelse af scriptet giver resultatet vist nedenfor.
| medlemsnummer | fulde_ navne | køn | fødselsdato | registreringsdato | fysisk adresse | postadresse | kontaktnummer | kreditkortnummer | |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Janet Jones | Kvinde | 21-07-1980 | NULL | First Street Plot nr. 4 | Privat taske | +0759 253 542 | janetjones@yagoo.cm | NULL |
| 2 | Janet Smith Jones | Kvinde | 23-06-1980 | NULL | Melrose 123 | NULL | NULL | jj@fstreet.com | NULL |
| 3 | Robert Phil | Mand | 12-07-1989 | NULL | 3rd Street 34 | NULL | 12345 | rm@tstreet.com | NULL |
| 4 | Gloria Williams | Kvinde | 14-02-1984 | NULL | 2nd Street 23 | NULL | NULL | NULL | NULL |
| 5 | Leonard Hofstadter | Mand | NULL | NULL | Træstøtte | NULL | 845738767 | NULL | NULL |
| 6 | Sheldon Cooper | Mand | NULL | NULL | Træstøtte | NULL | 976736763 | NULL | NULL |
| 7 | Rajesh Koothrappali | Mand | NULL | NULL | Træstøtte | NULL | 938867763 | NULL | NULL |
| 8 | Leslie Winkle | Mand | 14-02-1984 | NULL | Træstøtte | NULL | 987636553 | NULL | NULL |
| 9 | Howard Wolowitz | Mand | 24-08-1981 | NULL | South Park | PO Box 4563 | 987786553 | lwolowitz[at]email.me | NULL |
Kun 9 medlemmer er blevet returneret, fordi N i LIMIT-klausulen er større end antallet af poster i tabellen. Hvis man anmoder om 9 rækker, produceres det samme resultatsæt.
SELECT * FROM members LIMIT 9;
💡 Tip: LIMIT vælger rækker fra den rækkefølge, serveren tilfældigvis producerer. Tilføj en BESTIL BY klausul, når rækkernes identitet har betydning, ellers er det ikke garanteret, at "de første 10 medlemmer" betyder de samme ni personer to gange.
At begrænse antallet af rækker er den første halvdel af funktionen. At vælge, hvor vinduet starter, er den anden.
Brug af OFFSET-værdien i LIMIT-forespørgslen
OFFSET `value` bruges oftest sammen med LIMIT-nøgleordet. Det angiver, hvilken række serveren starter med at hente data fra, så rækker før dette punkt springes over.
Antag, at vi ønsker et begrænset antal medlemmer startende fra midten af tabellen. Scriptet nedenfor starter i anden række og begrænser resultatet til to poster.
SELECT * FROM `members` LIMIT 1, 2;
Udfører det i MySQL Workbench mod myflixdb giver følgende resultat.
| medlemsnummer | fulde_ navne | køn | fødselsdato | registreringsdato | fysisk adresse | postadresse | kontaktnummer | kreditkortnummer | |
|---|---|---|---|---|---|---|---|---|---|
| 2 | Janet Smith Jones | Kvinde | 23-06-1980 | NULL | Melrose 123 | NULL | NULL | jj@fstreet.com | NULL |
| 3 | Robert Phil | Mand | 12-07-1989 | NULL | 3rd Street 34 | NULL | 12345 | rm@tstreet.com | NULL |
Bemærk at her FORSKYDNING = 1, derfor er række #2 den første række, der returneres, og GRÆNSE = 2, derfor kommer kun 2 optegnelser tilbage.
I formen med to argumenter skrives forskydningen først og rækkeantallet derefter, hvilket er let at vende ved et uheld. MySQL accepterer også en eksplicit form, der fjerner tvetydigheden, og det er den, der foretrækkes i ny kode.
SELECT * FROM `members` LIMIT 2 OFFSET 1;
Begge sætninger returnerer de samme to rækker. Når offset'et er forstået, falder pagineringsmønsteret, som alle listeskærme er afhængige af, direkte ud af det.
Sådan paginerer du forespørgselsresultater med LIMIT og OFFSET
Paginering opdeler et stort resultatsæt i nummererede sider, og LIMIT sammen med OFFSET er den mekanisme, der gør det. To værdier styrer hver sideanmodning: sidestørrelsen, som er hvor mange poster der vises på én skærm, og det sidetal, som brugeren anmoder om.
Offsetet er afledt af dem med en enkelt formel.
-- OFFSET = page_size * (page_number - 1) SELECT membership_number, full_names FROM members ORDER BY membership_number ASC LIMIT 20 OFFSET 0; -- page 1
Side 2 beholder den samme grænse og flytter forskydningen frem med én sidestørrelse.
SELECT membership_number, full_names FROM members ORDER BY membership_number ASC LIMIT 20 OFFSET 20; -- page 2
Tre regler holder en pagineret liste korrekt og hurtig.
- Sortér altid: En pagineret forespørgsel uden ORDER BY kan vise den samme post på to forskellige sider og skjule en anden helt, fordi serveren frit kan ændre rækkefølgen mellem kald.
- Sortér på en unik kolonne: Uafgjorte rækker i sorteringskolonnen lader rækkefølgen af de uafgjorte rækker være udefineret. Problemet fjernes ved at sortere på primærnøglen eller tilføje den som en uafgjort nøgle.
- Se dybe sider: FORSKYDNING 100000 kræfter MySQL at læse hundrede tusinde rækker og smide dem væk, før de næste tyve returneres. Svartiden vokser med sidetallet.
Ved meget dyb paginering undgår keyset-paginering helt offset'et. I stedet for at tælle rækker, der skal springes over, husker forespørgslen den sidste nøgle fra den forrige side og spørger efter rækkerne bagefter.
SELECT membership_number, full_names FROM members WHERE membership_number > 20 -- last id from the previous page ORDER BY membership_number ASC LIMIT 20;
Denne formular forbliver hurtig uanset dybde, fordi indekset hopper direkte til starttasten i stedet for at gå gennem rækkerne foran. Ulempen er, at siderne skal gås i rækkefølge, så hopping Det er ikke længere muligt at gå direkte til side 500.
LIMIT i MySQL vs. TOP og HENT FØRST
LIMIT er ikke en del af alle SQL-dialekter, hvilket er vigtigt, så snart en forespørgsel skal flyttes mellem databasemotorer. MySQL, PostgreSQLog SQLite del LIMIT-nøgleordet. SQL Server bruger TOP, og Oracle bruger standard FETCH FIRST-klausulen. Tabellen nedenfor sammenligner de tre.
| Klausul | Engine (Motor) | Eksempel | Springer rækker over |
|---|---|---|---|
| GRÆNSE … FORSKYDNING | MySQL, PostgreSQL, SQLite | VÆLG * FRA medlemmer GRÆNSE 20 OFFSET 40; | Ja, med OFFSET |
| TOP | SQL Server | VÆLG TOP 20 * FRA medlemmer; | Nej, OFFSET … FETCH er påkrævet |
| HENT FØRST | Oracle, Db2, standard SQL | VÆLG * FRA medlemmer HENT KUN DE FØRSTE 20 RÆKKER; | Ja, med FORSKYDNING … RÆKKER |
Opførslen er den samme i begge tilfælde: sæt en grænse for antallet af rækker, og spring eventuelt et antal rækker over først. Kun stavningen ændres. En forespørgsel, der skal køre på mere end én maskine, bør derfor isolere rækkebegrænsende klausul i stedet for at sprede den gennem kodebasen.

