MySQL Limit
Apprenez à utiliser la clause LIMIT de MySQL en Python pour restreindre les résultats, implémenter la pagination et gérer efficacement les grands jeux de données.
La clause LIMIT contrôle le nombre de lignes renvoyées par une requête SELECT. Lorsque vous travaillez avec de grandes tables — des milliers ou des millions de lignes — récupérer tous les enregistrements en même temps gaspille de la mémoire et ralentit votre application. LIMIT vous permet de ne récupérer que les enregistrements dont vous avez réellement besoin.
Ce chapitre montre comment utiliser LIMIT en Python avec le package mysql-connector-python, notamment la pagination avec OFFSET, la combinaison de LIMIT avec ORDER BY, et les bonnes pratiques de gestion des erreurs.
Prérequis
Assurez-vous que le connecteur MySQL est installé avant d'exécuter l'un des exemples :
pip install mysql-connector-pythonTous les exemples supposent qu'une table customers existe dans une base de données appelée mydatabase. Vous pouvez en créer une en suivant le chapitre Python MySQL Create Table.
Fonctionnement de la clause LIMIT
La syntaxe de base restreint le jeu de résultats à un nombre fixe de lignes :
SELECT * FROM table_name LIMIT n;Pour ignorer un certain nombre de lignes avant de commencer le jeu de résultats, ajoutez OFFSET :
SELECT * FROM table_name LIMIT n OFFSET m;OFFSET m signifie « ignorer les m premières lignes ». C'est la base de la navigation page par page dans de grands jeux de données.
Récupérer un nombre fixe de lignes
L'exemple ci-dessous se connecte à une base de données MySQL et récupère uniquement les cinq premiers clients :
Récupérer les 5 premières lignes avec 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()La méthode fetchall() renvoie une liste de tuples — un tuple par ligne. Comme la requête limite déjà les résultats à cinq lignes, la liste contiendra au maximum cinq éléments, quel que soit le nombre total de lignes dans la table.
Utiliser LIMIT avec OFFSET pour la pagination
OFFSET décale la ligne de départ du résultat. Associé à LIMIT, il vous permet d'implémenter la pagination : la page 1 affiche les lignes 1–10, la page 2 affiche les lignes 11–20, et ainsi de suite.
La formule est : OFFSET = (page_number - 1) * page_size.
Récupérer la page 2 des résultats (lignes 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()Les espaces réservés %s sont remplis par le pilote du connecteur, qui gère les valeurs en toute sécurité et prévient les injections SQL. Ne construisez jamais les valeurs LIMIT ou OFFSET en concaténant des chaînes directement dans la requête.
Combiner LIMIT avec ORDER BY
Sans ORDER BY, la base de données peut renvoyer les lignes dans n'importe quel ordre. Lorsque vous utilisez LIMIT, vous souhaitez presque toujours un ordre prévisible — sinon les pages 1 et 2 pourraient contenir des lignes qui se chevauchent ou sont arbitraires.
Récupérer les 5 clients ajoutés le plus récemment
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()Dans MySQL, l'ordre d'évaluation est FROM → WHERE → ORDER BY → LIMIT, donc LIMIT s'applique toujours au jeu de résultats trié.
Récupérer une seule ligne avec fetchone()
Lorsque vous savez que vous n'avez besoin que d'une seule ligne — par exemple pour rechercher un enregistrement par clé primaire — vous pouvez limiter la requête à une ligne et utiliser fetchone() plutôt que fetchall(). Cela évite d'allouer une liste pour un résultat que vous n'utiliserez jamais :
Récupérer une seule ligne
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() renvoie un unique tuple ou None si le jeu de résultats est vide.
Créer une fonction de pagination réutilisable
Pour les applications réelles, il est pratique d'encapsuler la logique de pagination dans une fonction afin que le code appelant reste propre :
Assistant de pagination paginate() réutilisable
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()Notez que les noms de tables ne peuvent pas être passés en tant que paramètres %s — le connecteur ne prend pas en charge la paramètrisation des identifiants. La vérification isidentifier() protège contre les injections via l'argument du nom de table.
Erreurs courantes
LIMIT sans ORDER BY donne des résultats imprévisibles. MySQL ne garantit pas un ordre de lignes stable sauf si vous spécifiez ORDER BY. Deux requêtes identiques peuvent renvoyer des lignes différentes si la table est modifiée entre les appels.
Les grandes valeurs d'OFFSET sont lentes. LIMIT 10 OFFSET 1000000 oblige tout de même MySQL à analyser et à ignorer un million de lignes avant d'en renvoyer dix. Pour la pagination en profondeur sur de très grandes tables, envisagez la pagination par jeu de clés (également appelée pagination par curseur) : enregistrez le dernier id vu sur la page précédente et utilisez WHERE id > last_id LIMIT 10.
Ne construisez pas les valeurs LIMIT par concaténation de chaînes. Utilisez des espaces réservés %s ou, si la valeur est calculée en Python, assurez-vous qu'il s'agit d'un entier simple avant de l'incorporer dans la chaîne SQL.
Résumé
| Objectif | Modèle SQL |
|---|---|
| N premières lignes | SELECT ... LIMIT N |
| Ignorer M lignes, prendre N | SELECT ... LIMIT N OFFSET M |
| Page P de taille N | LIMIT N OFFSET (P-1)*N |
| Une seule ligne | SELECT ... LIMIT 1 + fetchone() |
| N premières lignes ordonnées | SELECT ... ORDER BY col LIMIT N |
Chapitres associés
- Python MySQL Select — interroger des lignes dans une table
- Python MySQL Where — filtrer les résultats avec des conditions
- Python MySQL Order By — trier les jeux de résultats
- Python MySQL Join — combiner plusieurs tables