web-dev-qa-db-fra.com

MySQL décalé des lignes infinies

Je voudrais construire une requête qui affiche tous les résultats dans une table, mais est compensée par 5 depuis le début de la table. Autant que je sache, le LIMIT de MySQL nécessite une limite ainsi qu'un décalage. Est-ce qu'il y a un moyen de faire ça?

101
stillinbeta

Depuis le Manuel MySQL sur LIMIT :

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

SELECT * FROM tbl LIMIT 95, 18446744073709551615;
140
Greg

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

SELECT * FROM somewhere LIMIT 18446744073709551610 OFFSET 5
22
Czimi

Comme indiqué dans d'autres réponses, MySQL suggère d'utiliser 18446744073709551615 comme nombre d'enregistrements dans la limite, mais considérez ceci: que feriez-vous si vous récupériez 18 446 744 073 709 551 615 enregistrements? En fait, que feriez-vous si vous aviez 1 000 000 000 d'enregistrements?

Peut-être que vous voulez plus d'un milliard d'enregistrements, mais mon point est qu'il y a une certaine limite sur le nombre que vous voulez, et c'est moins de 18 quintillions. Pour des raisons de stabilité, d'optimisation et éventuellement d'utilisation, je suggère de mettre une limite significative à la requête. Cela réduirait également la confusion pour quiconque n'a jamais vu ce nombre à l'aspect magique, et aurait l'avantage supplémentaire de communiquer au moins le nombre d'enregistrements que vous êtes prêt à traiter à la fois.

Si vous devez vraiment obtenir les 18 quintillions d'enregistrements de votre base de données, peut-être que vous voulez vraiment les récupérer par incréments de 100 millions et boucler 184 milliards de fois.

7
cesoid

Une autre approche consisterait à sélectionner une colonne auto-incrémentée puis à la filtrer à l'aide de HAVING.

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

Mais je m'en tiendrai probablement à l'approche de la limite supérieure.

5
jishi

Aujourd'hui, je lisais 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 consiste, comme suggéré, à utiliser LIMIT x,yx est l'offset et y la dernière ligne que vous souhaitez renvoyer. Cependant, comme je l'ai découvert, ce n'est pas le moyen le plus efficace de le faire. Si vous avez une colonne d'incrémentation automatique, vous pouvez tout aussi facilement utiliser une instruction SELECT avec une clause WHERE indiquant à partir de quel enregistrement vous souhaitez commencer.

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

Il semble que mysql obtienne tous les résultats lorsque vous utilisez LIMIT, puis ne vous montre que les enregistrements qui correspondent à l'offset: pas le meilleur pour les performances.

Source: réponse à cette question Forums MySQL . Prenez juste note, la question a environ 6 ans.

0
fed

Vous pouvez utiliser une instruction MySQL avec LIMIT:

START TRANSACTION;
SET @my_offset = 5;
SET @rows = (SELECT COUNT(*) FROM my_table);
PREPARE statement FROM 'SELECT * FROM my_table LIMIT ? OFFSET ?';
EXECUTE statement USING @rows, @my_offset;
COMMIT;

Testé dans MySQL 5.5.44. Ainsi, nous pouvons éviter l'insertion du numéro 18446744073709551615.

note: la transaction s'assure que la variable @rows est en accord avec la table considérée dans l'exécution de l'instruction.

0
sissi_luaty