web-dev-qa-db-fra.com

MySQL: récupérer une grande sélection par morceaux

J'ai choisi avec plus de

70 millions de lignes

Je voudrais enregistrer les données sélectionnées dans le seul grand fichier csv sur win2012 R2

Q: Comment récupérer les données de MySQL par des chanks pour de meilleures performances?

parce que quand j'essaie d'en enregistrer un, le grand choix que j'ai

des erreurs de mémoire insuffisante

17
Toren

Vous pouvez essayer d'utiliser la fonction LIMIT. Si tu fais ça:

SELECT * FROM MyTable ORDER BY whatever LIMIT 0,1000

Vous obtiendrez les 1 000 premières lignes. La première valeur LIMIT (0) définit la ligne de départ dans le jeu de résultats. Il est indexé zéro, donc 0 signifie "la première ligne". La deuxième valeur LIMIT est le nombre maximal de lignes à récupérer. Pour obtenir les prochains ensembles de 1 000, procédez comme suit:

SELECT * FROM MyTable ORDER BY whatever LIMIT 1000,1000 -- rows 1,001 - 2,000
SELECT * FROM MyTable ORDER BY whatever LIMIT 2000,1000 -- rows 2,001 - 3,000

Etc. Lorsque le SELECT ne renvoie aucune ligne, vous avez terminé.

Cependant, cela ne suffit pas, car toute modification apportée à la table pendant que vous traitez vos lignes 1K à la fois annulera la commande. Pour figer les résultats dans le temps, commencez par interroger les résultats dans une table temporaire:

CREATE TEMPORARY TABLE MyChunkedResult AS (
  SELECT *
  FROM MyTable
  ORDER BY whatever
);

Note: c'est une bonne idée de s'assurer que la table temporaire n'existe pas au préalable:

DROP TEMPORARY TABLE IF EXISTS MyChunkedResult;

Quoi qu'il en soit, une fois la table temporaire en place, retirez les morceaux de ligne à partir de là:

SELECT * FROM MyChunkedResult LIMIT 0, 1000;
SELECT * FROM MyChunkedResult LIMIT 1000,1000;
SELECT * FROM MyChunkedResult LIMIT 2000,1000;
.. and so on.

Je vous laisse le soin de créer la logique qui calculera la valeur limite après chaque bloc et vérifiera la fin des résultats. Je recommanderais également des morceaux beaucoup plus gros que 1 000 enregistrements; c'est juste un chiffre que j'ai choisi.

Enfin, il est bon de supprimer la table temporaire lorsque vous avez terminé:

DROP TEMPORARY TABLE MyChunkedResult;
32
Ed Gibbs

Le LIMIT OFFSET l'approche ralentit la requête lorsqu'une taille des données est très grande. Une autre approche consiste à utiliser quelque chose appelé pagination Keyset. Il nécessite un identifiant unique dans votre requête, que vous pouvez utiliser comme signet pour pointer vers la dernière ligne de la page précédente. La page suivante est récupérée à l'aide du dernier signet. Par exemple:

SELECT user_id, name, date_created
FROM users
WHERE user_id > 0
ORDER BY user_id ASC
LIMIT 10 000;

Si l'ensemble de résultats ci-dessus renvoie la dernière ligne avec user_id comme 12345, vous pouvez l'utiliser pour récupérer la page suivante comme suit:

SELECT user_id, name, date_created
FROM users
WHERE user_id > 12345
ORDER BY user_id ASC
LIMIT 10 000;

Pour plus de détails, vous pouvez jeter un œil à ceci page .

1
prafi