MySQL Limit
Aprenda a usar a cláusula MySQL LIMIT em Python para limitar resultados, implementar paginação e lidar com grandes conjuntos de dados.
A cláusula LIMIT controla quantas linhas uma consulta SELECT retorna. Ao trabalhar com tabelas grandes — com milhares ou milhões de linhas — buscar todos os registros de uma vez desperdiça memória e torna a aplicação mais lenta. O LIMIT permite recuperar apenas os registros que você realmente precisa.
Este capítulo mostra como usar o LIMIT em Python com o pacote mysql-connector-python, incluindo paginação com OFFSET, combinação de LIMIT com ORDER BY e boas práticas para tratamento de erros.
Pré-requisitos
Certifique-se de que o conector MySQL está instalado antes de executar qualquer um dos exemplos:
pip install mysql-connector-pythonTodos os exemplos assumem que existe uma tabela customers em um banco de dados chamado mydatabase. Você pode criá-la seguindo o capítulo Python MySQL Create Table.
Como a cláusula LIMIT funciona
A sintaxe básica restringe o conjunto de resultados a um número fixo de linhas:
SELECT * FROM table_name LIMIT n;Para ignorar um número de linhas antes de iniciar o conjunto de resultados, adicione OFFSET:
SELECT * FROM table_name LIMIT n OFFSET m;OFFSET m significa "ignorar as primeiras m linhas". Esta é a base da navegação página a página por grandes conjuntos de dados.
Buscando um número fixo de linhas
O exemplo abaixo conecta-se a um banco de dados MySQL e recupera apenas os cinco primeiros clientes:
Recuperar as primeiras 5 linhas com LIMIT
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
mycursor.execute("SELECT * FROM customers LIMIT 5")
results = mycursor.fetchall()
for row in results:
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mycursor:
mycursor.close()
if mydb.is_connected():
mydb.close()O método fetchall() retorna uma lista de tuplas — uma tupla por linha. Como a consulta já limita os resultados a cinco linhas, a lista conterá no máximo cinco itens, independentemente do número total de linhas na tabela.
Usando LIMIT com OFFSET para paginação
OFFSET desloca a linha inicial do resultado. Combinado com LIMIT, permite implementar paginação: a página 1 exibe as linhas 1–10, a página 2 exibe as linhas 11–20, e assim por diante.
A fórmula é: OFFSET = (page_number - 1) * page_size.
Recuperar a página 2 dos resultados (linhas 11–20)
import mysql.connector
from mysql.connector import Error
page_number = 2
page_size = 10
offset = (page_number - 1) * page_size # evaluates to 10
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
sql = "SELECT * FROM customers LIMIT %s OFFSET %s"
mycursor.execute(sql, (page_size, offset))
results = mycursor.fetchall()
for row in results:
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mycursor:
mycursor.close()
if mydb.is_connected():
mydb.close()Os marcadores %s são preenchidos pelo driver do conector, que trata os valores com segurança e previne injeção de SQL. Nunca construa os valores de LIMIT ou OFFSET concatenando strings diretamente na consulta.
Combinando LIMIT com ORDER BY
Sem ORDER BY, o banco de dados pode retornar as linhas em qualquer ordem. Quando você usa LIMIT, quase sempre deseja uma ordem previsível — caso contrário, a página 1 e a página 2 podem conter linhas sobrepostas ou arbitrárias.
Recuperar os 5 clientes adicionados mais recentemente
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
# Sort by id descending so the newest rows come first, then take 5
mycursor.execute("SELECT * FROM customers ORDER BY id DESC LIMIT 5")
results = mycursor.fetchall()
for row in results:
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mycursor:
mycursor.close()
if mydb.is_connected():
mydb.close()No MySQL, a ordem de avaliação é FROM → WHERE → ORDER BY → LIMIT, portanto o LIMIT sempre opera sobre o conjunto de resultados ordenado.
Buscando uma única linha com fetchone()
Quando você sabe que precisa de apenas uma linha — como ao buscar um registro pela chave primária — pode limitar a consulta a uma linha e usar fetchone() em vez de fetchall(). Isso evita alocar uma lista para um resultado que nunca será utilizado:
Recuperar uma única linha
import mysql.connector
from mysql.connector import Error
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
mycursor.execute("SELECT * FROM customers LIMIT 1")
row = mycursor.fetchone()
if row:
print(row)
else:
print("No records found.")
except Error as e:
print(f"Error: {e}")
finally:
if mycursor:
mycursor.close()
if mydb.is_connected():
mydb.close()fetchone() retorna uma única tupla ou None se o conjunto de resultados estiver vazio.
Criando uma função de paginação reutilizável
Em aplicações reais, é conveniente encapsular a lógica de paginação em uma função para manter o código chamador limpo:
Helper paginate() reutilizável
import mysql.connector
from mysql.connector import Error
def paginate(cursor, table, page, page_size=10):
"""Return one page of rows from *table*.
Args:
cursor: An active mysql.connector cursor.
table: Name of the table to query (string).
page: 1-based page number.
page_size: Number of rows per page (default 10).
Returns:
A list of row tuples, or an empty list when no rows remain.
"""
offset = (page - 1) * page_size
# Table names cannot be parameterised, so validate the name first.
if not table.isidentifier():
raise ValueError(f"Invalid table name: {table!r}")
sql = f"SELECT * FROM `{table}` LIMIT %s OFFSET %s"
cursor.execute(sql, (page_size, offset))
return cursor.fetchall()
try:
mydb = mysql.connector.connect(
host="localhost",
user="yourusername",
password="yourpassword",
database="mydatabase"
)
mycursor = mydb.cursor()
# Print the first three pages
for page in range(1, 4):
rows = paginate(mycursor, "customers", page=page, page_size=5)
if not rows:
print(f"Page {page}: no more rows.")
break
print(f"--- Page {page} ---")
for row in rows:
print(row)
except Error as e:
print(f"Error: {e}")
finally:
if mycursor:
mycursor.close()
if mydb.is_connected():
mydb.close()Observe que nomes de tabelas não podem ser passados como parâmetros %s — o conector não suporta a parametrização de identificadores. A verificação com isidentifier() protege contra injeção por meio do argumento com o nome da tabela.
Erros comuns
LIMIT sem ORDER BY produz resultados imprevisíveis. O MySQL não garante uma ordem estável de linhas a menos que você especifique ORDER BY. Duas consultas idênticas podem retornar linhas diferentes se a tabela for modificada entre as chamadas.
Valores grandes de OFFSET são lentos. LIMIT 10 OFFSET 1000000 ainda faz o MySQL varrer e descartar um milhão de linhas antes de retornar dez. Para paginação profunda em tabelas muito grandes, considere a paginação por keyset (também chamada de paginação baseada em cursor): registre o último id visto na página anterior e use WHERE id > last_id LIMIT 10.
Não construa valores de LIMIT por concatenação de strings. Use marcadores %s ou, se o valor for calculado em Python, certifique-se de que seja um inteiro simples antes de incorporá-lo na string SQL.
Resumo
| Objetivo | Padrão SQL |
|---|---|
| Primeiras N linhas | SELECT ... LIMIT N |
| Ignorar M linhas, buscar N | SELECT ... LIMIT N OFFSET M |
| Página P de tamanho N | LIMIT N OFFSET (P-1)*N |
| Apenas uma linha | SELECT ... LIMIT 1 + fetchone() |
| Primeiras N ordenadas | SELECT ... ORDER BY col LIMIT N |
Capítulos relacionados
- Python MySQL Select — consultando linhas de uma tabela
- Python MySQL Where — filtrando resultados com condições
- Python MySQL Order By — ordenando conjuntos de resultados
- Python MySQL Join — combinando múltiplas tabelas