MySQL Limit Data

La Lakshmi Priya Updated 04 Nov 2026
5 min read ·Lesson 223 of 229

MySQL Limit Data Returning Only Some Rows In simple terms: A product table might contain thousands of rows, but a homepage shows the "Top 3 best sellers", a search page shows 20 results at a time, and an existence check needs just one row. LIMIT tells the database to return at most a certain number of rows — fewer rows to send, process, and display.

Technically: LIMIT count restricts the result to the first count rows; LIMIT count OFFSET skip (or LIMIT skip, count) skips rows first. LIMIT is applied after WHERE and ORDER BY, so it must be combined with ORDER BY to return meaningful, predictable rows. It also works with UPDATE and DELETE.

The examples use the products from MySQL Insert Multiple (after MySQL Update Data, the Desk Lamp has 6 in stock).

Syntax SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT count; SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT count OFFSET skip; SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT skip, count; -- same as above, older form Example Returns LIMIT 3 The first 3 rows LIMIT 2 OFFSET 2 Rows 3 and 4 (skip 2, take 2) LIMIT 2, 2 Same as LIMIT 2 OFFSET 2 (note the reversed order: skip first) Top-N Queries <?php require DIR . '/src/db.php';

$db = db();

echo "Most expensive:\n"; foreach ($db->query('SELECT name, price FROM products ORDER BY price DESC LIMIT 3') as $row) { echo " {$row['name']} (₹{$row['price']})\n"; }

echo "Cheapest:\n"; foreach ($db->query('SELECT name, price FROM products ORDER BY price ASC LIMIT 2') as $row) { echo " {$row['name']} (₹{$row['price']})\n"; } Output Most expensive: Desk Lamp (₹1299.00) Backpack (₹899.00) Wireless Mouse (₹599.00) Cheapest: Gel Pen (₹20.00) Notebook A5 (₹60.00) How It Works ORDER BY price DESC sorts all products from most to least expensive. LIMIT 3 keeps only the first three rows of that sorted result. Changing only the direction and the limit gives the cheapest products. Without ORDER BY, LIMIT 3 returns "some three rows" — which three is not defined and may change. Always sort before limiting.

Skipping Rows With OFFSET <?php require DIR . '/src/db.php';

$stmt = db()->prepare('SELECT id, name FROM products ORDER BY id LIMIT ? OFFSET ?');

$perPage = 2; $offset = 2; // skip the first page $stmt->bind_param('ii', $perPage, $offset); $stmt->execute();

foreach ($stmt->get_result() as $row) { echo "#{$row['id']} {$row['name']}\n"; } Output #3 Desk Lamp #4 Backpack OFFSET 2 skips the first two rows (IDs 1 and 2); LIMIT 2 then takes the next two. When LIMIT and OFFSET values come from the request (for example, a page number), pass them as integer parameters with bind_param('ii', ...). Values sent as strings, as with execute([...]) or execute_query(), are not accepted reliably for LIMIT. This is the basis of page-by-page navigation, covered fully in Pagination with PHP.

LIMIT 1 for Single Rows and Existence Checks When you need at most one row, LIMIT 1 lets MySQL stop searching as soon as it finds a match:

<?php require DIR . '/src/db.php';

function emailExists(mysqli $db, string $email): bool { return $db->execute_query('SELECT 1 FROM customers WHERE email = ? LIMIT 1', [$email])->num_rows === 1; }

var_dump(emailExists(db(), 'asha@example.com')); var_dump(emailExists(db(), 'nobody@example.com')); Output bool(true) bool(false) SELECT 1 returns a constant instead of real columns, because only the existence of a row matters. (For inserts, still rely on the UNIQUE constraint rather than a check-then-insert sequence — see MySQL Insert Data.)

Top-N per Group (MySQL 8 Window Functions) LIMIT applies to the whole result. To get, for example, the most expensive product in each category, use the window function ROW_NUMBER() (MySQL 8.0+):

<?php require DIR . '/src/db.php';

$sql = ' SELECT category, name, price FROM ( SELECT category, name, price, ROW_NUMBER() OVER (PARTITION BY category ORDER BY price DESC) AS position FROM products ) AS ranked WHERE position = 1 ORDER BY category ';

foreach (db()->query($sql) as $row) { printf("%-12s %-12s ₹%s\n", $row['category'], $row['name'], $row['price']); } Output bags Backpack ₹899.00 electronics Desk Lamp ₹1299.00 stationery Notebook A5 ₹60.00 ROW_NUMBER() numbers the rows within each category (PARTITION BY category) by descending price. Keeping only position 1 gives the top product per category. Change the condition to position <= 3 for the top three per category.

LIMIT With UPDATE and DELETE LIMIT restricts how many rows a modifying statement may affect:

-- Process the oldest 100 pending notifications UPDATE notifications SET status = 'processing' WHERE status = 'pending' ORDER BY created_at LIMIT 100;

-- Delete old log entries in manageable chunks DELETE FROM activity_log WHERE created_at < '2025-01-01' LIMIT 1000; This is useful for batch jobs: each run handles a bounded amount of work, keeping locks short. (LIMIT with UPDATE/DELETE supports a row count only — no OFFSET.)

Performance: Large Offsets LIMIT 20 OFFSET 100000 does not jump directly to row 100,001: MySQL must find and discard the first 100,000 rows. For deep pages in large tables, this becomes slow. Keyset pagination ("seek method") avoids the problem by continuing after the last seen value instead of counting rows:

SELECT id, name FROM products WHERE id > ? ORDER BY id LIMIT 20; Both techniques are compared in Pagination with PHP.

Common Mistakes LIMIT Without ORDER BY Effect: Unpredictable rows; pages may overlap or skip rows.

Fix: Always sort, with a unique tie-breaker column.

Mixing Up LIMIT skip, count Effect: LIMIT 20, 10 returns 10 rows after skipping 20 — not 20 rows.

Fix: Prefer the clearer LIMIT count OFFSET skip form.

Passing Limits as Strings or Unvalidated Input Effect: Errors, or huge result sets when users request limit=1000000.

Fix: Validate as integers, enforce a maximum, and bind with type i.

Fetching Everything and Slicing in PHP Effect: Wasted memory and time.

Fix: Let the database limit the result.

Best Practices Combine LIMIT with a deterministic ORDER BY. Validate limit and offset values, cap them, and bind them as integers. Use LIMIT 1 for single-row lookups and existence checks. Use window functions for top-N-per-group results. Prefer keyset pagination for deep pages in large tables. Official reference: https://www.php.net/manual/en/mysqli.query.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else User-defined Functions Slicing Strings Function Arguments PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators AJAX PHP AJAX Database AJAX XML AJAX Live Search AJAX Poll AJAX with JSON Security Introduction Password Hashing SQL Injection Prevention XSS Prevention Garbage Collection Project: Simple Blog PHP What is OOP PHP Classes/Objects The $this Keyword Access Array Items Update Array Items Add Array Items Remove Array Items Sorting Arrays Multidimensional Arrays Array Destructuring Array Spread Operator Search in Arrays Merge Arrays PHP Abstract Classes PHP Interfaces Polymorphism PHP Traits PHP Static Methods PHP Static Properties Late Static Binding Magic Methods Object Cloning MySQL Database MySQL Connect MySQL Create DB MySQL Create Table MySQL Insert Data MySQL Get Last ID MySQL Insert Multiple MySQL Prepared MySQL Select Data MySQL Where Debugging PHP Project: Image Upload Gallery $_SESSION $_ENV PHP RegEx RegEx Patterns Heredoc and Nowdoc RegEx Modifiers preg_match preg_replace preg_split PHP RegEx Functions Nullable Types Mixed and Never Types Nullsafe Operator PHP Attributes PHP Fibers Readonly Classes Property Hooks (PHP 8.4) Asymmetric Visibility (PHP 8.4) Reflection API SPL Data Structures Composer PHP Form Handling PDO Transactions PDO Error Handling PHP XML Parsers PHP SimpleXML Parser PHP SimpleXML - Get PHP XML Expat Parser PHP DOM Parser PHP XMLReader PHP XMLWriter AJAX Intro PHP Class Constants Encryption with Sodium Recursive Functions Variable Functions Anonymous Functions Closures Arrow Functions First-class Callable Syntax PHP Arrays Indexed Arrays Associative Arrays Create Arrays Variables Scope Static Variables Variable Variables PHP Echo / Print PHP printf / sprintf PHP Data Types PHP Booleans PHP NULL PHP Strings String Functions array_map / array_filter / array_reduce Array Functions PHP Superglobals $GLOBALS What Is `$_SERVER` ? $_REQUEST $_POST $_GET $_FILES $_COOKIE PHP Type Juggling MySQL Order By MySQL Delete Data MySQL Update Data MySQL Limit Data MySQL Joins with PHP Pagination with PHP PDO Introduction PDO Connect PDO Prepared Statements PDO Fetch Modes
Ask about this post
AI Ask about this post

Ask questions about MySQL Limit Data and get answers drawn from it.

Signed-in readers only.