Databases 8 min read

Why LIMIT with Large Offsets Slows MySQL Queries and How to Optimize It

The article explains why using LIMIT with a large offset in MySQL causes severe performance degradation, demonstrates the problem with real data, and shows how rewriting the query with a sub‑query that selects only primary keys dramatically reduces execution time by avoiding massive random I/O and buffer‑pool pollution.

Top Architect
Top Architect
Top Architect
Why LIMIT with Large Offsets Slows MySQL Queries and How to Optimize It

This article investigates the performance issue caused by MySQL queries that use LIMIT offset, count with a large offset, showing that a query scanning 9555695 rows took 16 s while an optimized version took only 347 ms.

Problem statement : A financial transaction table with 5.2 million rows is queried with SELECT * FROM test WHERE val=4 LIMIT 300000,5. The original query scans 300 005 index entries and corresponding clustered rows, resulting in heavy random I/O and a 15.98 s execution time.

Optimization approach : Move the filter into a sub‑query that selects only the primary key IDs, then join back to retrieve the full rows:

SELECT  各种字段
FROM `table_name` main_table
RIGHT JOIN (
  SELECT  子查询只查主键
  FROM `table_name`
  WHERE 各种条件
  LIMIT 0,10
) temp_table ON temp_table.主键 = main_table.主键;

This reduces the number of random I/O operations to the number of rows actually needed (5), cutting execution time to 0.38 s.

Technical explanation : With a large offset, MySQL must traverse the index leaf nodes for every row up to the offset, then perform a “row‑lookup” on the clustered index for each, discarding the first 300 000 rows. This results in many unnecessary data‑page reads and pollutes the InnoDB buffer pool.

Experimental verification : The author runs two queries—one with the original LIMIT and one with the sub‑query join—while monitoring information_schema.INNODB_BUFFER_PAGE. The original query loads 4 098 data pages and 208 index pages into the buffer pool; the optimized query loads only 5 data pages and 390 index pages, confirming the reduction in I/O.

Additional notes : To avoid buffer‑pool contamination across restarts, the settings innodb_buffer_pool_dump_at_shutdown and innodb_buffer_pool_load_at_startup should be disabled.

Conclusion : Rewriting large‑offset LIMIT queries to first fetch primary keys in a sub‑query and then join back eliminates unnecessary scans, dramatically improves performance, and preserves buffer‑pool efficiency.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

mysqlLIMITindexbuffer pool
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.