122 votes

MySQL décalage de lignes infini

Je voudrais construire une requête qui affiche tous les résultats dans un tableau, mais est décalée de 5 à partir du début du tableau. Autant que je sache, le LIMIT de MySQL nécessite une limite ainsi qu'un décalage. Y a-t-il un moyen de faire cela?

2 votes

C'est une question totalement valable, mais je me demande si ce qui serait mieux serait de tout prendre et d'ignorer les premiers enregistrements de manière programmatique. Étant donné l'horreur de ce qui semble être la meilleure réponse (limite 5, 18446744073709551615), je favoriserais fortement le contournement des limitations de MySQL LIMIT.

3 votes

@cesoid que se passe-t-il si vous voulez limiter 5000, 18446744073709551615. Vous ne allez pas récupérer 5000 lignes supplémentaires juste pour que votre code ait l'air joli.

0 votes

@user3576887 Je pense que vous avez raison, je venais juste de considérer la question ci-dessus en supposant que 5 était la seule exigence, plutôt qu'une quantité variable qui pourrait être beaucoup plus grande (et plutôt que de résoudre le problème de quelqu'un d'autre).

159voto

Greg Points 132247

De la Manuel MySQL sur LIMIT:

Pour récupérer toutes les lignes à partir d'un certain décalage jusqu'à la fin de l'ensemble de résultats, vous pouvez utiliser un nombre important pour le deuxième paramètre. Cette instruction récupère toutes les lignes de la 96ème ligne à la dernière :

SELECT * FROM tbl LIMIT 95, 18446744073709551615;

116 votes

Affreux! Je suis venu ici en espérant que MySQL rende la clause Limit facultative, comme c'est le cas, mais aussi avec un offset fourni... mais non! J'ai vu ce 18446744073709551615 éparpillé dans tout le code et je blâmais des programmeurs paresseux, mais c'est une caractéristique de conception!

9 votes

Traduction : réponse affreuse, mais c'est officiel de la documentation MySQL. Que puis-je dire @_@

23 votes

18446744073709551615 est égal à 2^64-1 pour ceux qui se demandaient. Vous devrez faire attention car vous ne pourrez pas stocker cette valeur dans un entier 32 bits. Vous devez vous assurer de stocker ceci en tant que chaîne de caractères pour garantir la compatibilité.

27voto

Czimi Points 1145

Comme vous l'avez mentionné, LIMIT est requis, vous devez donc utiliser la limite la plus grande possible, qui est de 18446744073709551615 (maximum de UNSIGNED BIGINT)

SELECT * FROM somewhere LIMIT 18446744073709551610 OFFSET 5

40 votes

Wow, est-ce la solution officielle de l'équipe MySQL?

1 votes

Je me demande pourquoi les gens utilisent encore MySQL alors qu'il y a PostgreSQL disponible...

5voto

jishi Points 10442

Une autre approche consisterait à sélectionner une colonne auto-incrémentée, puis à la filtrer en utilisant HAVING.

SET @a := 0; 
select @a:=@a + 1 AS counter, table.* FROM table 
HAVING counter > 4

Mais je resterais probablement avec l'approche de la limite élevée.

0 votes

Merci, et je me demande comment je peux mettre une telle requête dans une déclaration PHP! je veux dire de cette manière $sql = 'SET @a :=0 SELECT .....';

-1voto

Je sais que c'est vieux mais je n'ai pas vu de réponse similaire donc voici la solution que j'utiliserais.

Tout d'abord, j'exécuterais une requête de comptage sur la table pour voir combien d'enregistrements existent. Cette requête est rapide et normalement le temps d'exécution est négligeable. Quelque chose comme :

SELECT COUNT(*) FROM table_name;

Ensuite, je construirais ma requête en utilisant le résultat obtenu du comptage comme ma limite (puisque c'est le nombre maximum de lignes que la table pourrait potentiellement retourner). Quelque chose comme :

SELECT * FROM table_name LIMIT count_result OFFSET desired_offset;

Ou éventuellement quelque chose comme :

SELECT * FROM table_name LIMIT desired_offset, count_result;

Bien sûr, si nécessaire, vous pourriez soustraire desired_offset de count_result pour obtenir une valeur réelle et précise à fournir en tant que limite. Passer la valeur "18446744073709551610" n'a tout simplement pas de sens si je peux déterminer une limite appropriée à fournir.

2 votes

Sélectionner count(*) sur une table avec 7M d'enregistrements prend environ 17s

-2voto

fed Points 218

Juste aujourd'hui, je lisais sur la meilleure façon d'obtenir d'énormes quantités de données (plus d'un million de lignes) à partir d'une table mysql. Une façon est, comme suggéré, d'utiliser LIMIT x, yx est le décalage et y la dernière ligne que vous souhaitez obtenir. Cependant, comme je l'ai découvert, ce n'est pas la manière la plus efficace de le faire. Si vous avez une colonne auto-incrémentée, vous pouvez aussi facilement utiliser une instruction SELECT avec une clause WHERE indiquant à partir de quelle ligne vous souhaitez commencer.

Par exemple, SELECT * FROM table_name WHERE id > x;

Il semble que mysql obtient tous les résultats lorsque vous utilisez LIMIT et ne vous montre ensuite que les enregistrements qui correspondent au décalage: ce n'est pas le mieux en termes de performances.

Source: Réponse à cette question Forums MySQL. Remarquez cependant que la question date de 6 ans.

15 votes

Cela donnera des résultats incorrects si vous avez déjà supprimé un enregistrement. Cette méthode est particulièrement dangereuse, car elle fonctionne la plupart du temps et échoue silencieusement quand ce n'est pas le cas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X