Supprimer de grandes quantités (4 millions de lignes) de données mysql de manière efficace et très régulière

10

Nous avons une table mysql qui à tout moment compte environ 12 millions de lignes. Nous devons supprimer les anciennes données pour garder la taille de la table quelque peu gérable.

À l'heure actuelle, nous exécutons cette requête quotidiennement, à minuit, à l'aide d'un travail cron:

DELETE FROM table WHERE endTime < '1393632001'

La dernière fois que la requête a été exécutée, elle a examiné 4 602 400, a pris plus de 3 minutes et le processeur a traversé le toit.

Augmentation du processeur à minuit

Que pouvons-nous faire pour empêcher le processeur, les connexions synchrones de la base de données, la profondeur des repères de disque, etc. de monter de façon déraisonnable tout en effaçant les anciennes données?

PS: Vous remarquerez que la requête se produit en fait à un moment assez inopportun de notre cycle d'utilisation. Supposons que nous ayons déjà décalé le timing de la requête pour qu'elle se produise au point d'utilisation le plus bas chaque jour. De plus, il n'y a pas d'index sur "endTime" et je préférerais le garder de cette façon si possible car il y a une tonne de données insérées très régulièrement, et pas beaucoup de recherche.


la source
peut-être utiliser des tâches cron pour supprimer toutes les 10 minutes et 100k par round ou toutes les 5 minutes 50k par round
de plus petits morceaux sur une base plus régulière?
ok, mais il semble que cela pourrait paralyser notre expérience utilisateur pendant de plus longues périodes :) tout ce que nous pouvons faire en termes de requête / conception?
1
186k utilisateurs, pas de type db dédié?
1
Vous obtiendrez de meilleures réponses sur "Administrateurs de bases de données"
James Anderson

Réponses:

13

La solution à votre problème est une capacité MySQL appelée "partitionnement". La documentation est ici .

Le partitionnement stocke une seule table dans des "partitions" distinctes. Ceux-ci sont définis par une expression particulière, généralement une valeur ou une plage de colonne. Dans votre cas, cela serait probablement basé sur endTime- en supposant qu'il est connu lorsqu'un enregistrement est créé et qu'il ne change pas.

Vous stockeriez la valeur d'une journée endTimedans chaque partition. Ensuite, l'étape de suppression serait de tronquer une partition plutôt que de supprimer un groupe de lignes dans une grande table. La troncature de partition serait une méthode beaucoup plus rapide.

Gordon Linoff
la source
wow, c'était incroyablement utile, et semble être une solution parfaite. Il est temps de lire sur le partitionnement! Merci!
Bien que le partitionnement puisse être une bonne solution, méfiez-vous des frais généraux - cela peut ralentir considérablement vos requêtes. D'ailleurs la table tronquée n'est pas instantanée non plus. Je considérerais pt-archiver. Vous pouvez résoudre vos problèmes avec des pointes et garder votre table aussi simple qu'elle est maintenant
akuzminsky