La manipulation de très grandes données avec mysql
Désolé pour le long post!
J'ai une base de données contenant environ 30 tables (moteur InnoDB). Seulement deux de ces tableaux, à savoir, "transaction" et "shift" sont assez grandes (le premier de 1,5 million de lignes et maj a 23k lignes). Maintenant tout fonctionne très bien et je n'ai pas de problème avec la base de données actuelle de la taille.
Cependant, nous aurons une base de données similaire (mêmes types de données, la conception ,..) mais en beaucoup plus grand, par exemple, la "transaction" table sur 1 milliard d'enregistrements (environ 2,3 millions de transactions par jour) et nous réfléchissons à la façon dont nous devrions traiter avec un tel volume de données MySQL? (il est à la fois en lecture et en écriture intensive). J'ai lu beaucoup de postes connexes pour voir si Mysql (et plus spécifiquement le moteur InnoDB) peut effectuer bien avec des milliards d'enregistrements, mais je n'ai encore quelques questions. Certains de ces related posts que j'ai lu sont les suivantes:
- Pouvez MySQL raisonnablement effectuer des requêtes sur des milliards de lignes?
- Est InnoDB (MySQL 5.5.8) le bon choix pour plusieurs milliards de lignes?
- Le meilleur magasin de données pour des milliards de lignes
- Grand comment une base de données MySQL obtenir avant la performance commence à se dégrader
- Pourquoi MySQL peut être très lente avec des grandes tables?
- Peut gérer des tables Mysql qui pourra contenir environ 300 millions de disques?
Ce que j'ai compris jusqu'à présent pour améliorer les performances de très grandes tables:
- (pour les tables innoDB qui est mon cas) l'augmentation de la
innodb_buffer_pool_size
(par exemple, jusqu'à 80% de la RAM).
Aussi, j'ai trouvé quelques autres performances MySQL modulable paramètres ici, dans
percona blog - avoir un bon index sur la table (à l'aide de EXPLAN sur des requêtes)
- partitionnement de la table
- MySQL de Fragmentation ou de clustering
Voici mes questions/confusions:
-
Sur le partitionnement, j'ai quelques doutes à savoir si nous devrions ou non de l'utiliser. D'une part, beaucoup de gens ont suggéré afin d'améliorer les performances lors de la table est très grande. D'autre part, j'ai lu de nombreux messages disant qu'il n'a pas d'améliorer les performances des requêtes et cela ne fait pas de requêtes de courir plus vite (par exemple, ici et ici). Aussi, j'ai lu dans Manuel De Référence De MySQL que InnoDB clés étrangères et MySQL partitionnement ne sont pas compatibles (nous avons les clés étrangères).
-
Concernant l'index, maintenant ils sont bien, mais que j'ai compris, pour les très grandes tables d'indexation est plus restrictive (comme Kevin Bedell mentionné dans sa réponse ici). En outre, les indices de vitesse jusqu'lit tout ralentir écrire (insert/update). Donc, pour le nouveau projet similaire que nous aurons cette grande DB, devrions-nous d'abord insérer/charger toutes les données, puis créer des index? (pour accélérer l'insertion)
-
Si nous ne pouvons pas utiliser le partitionnement pour notre grande table ("transaction" de la table), ce qui est une autre option pour améliorer les performances? (à l'exception de MySQl variable de paramètres tels que
innodb_buffer_pool_size
). Devrions-nous utiliser Mysql clusters? (nous avons aussi beaucoup de jointures)
MODIFIER
C'est le show create table
déclaration pour notre plus grand table nommée "opération":
CREATE TABLE `transaction` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`terminal_transaction_id` int(11) NOT NULL,
`fuel_terminal_id` int(11) NOT NULL,
`fuel_terminal_serial` int(11) NOT NULL,
`xboard_id` int(11) NOT NULL,
`gas_station_id` int(11) NOT NULL,
`operator_id` text NOT NULL,
`shift_id` int(11) NOT NULL,
`xboard_total_counter` int(11) NOT NULL,
`fuel_type` int(11) NOT NULL,
`start_fuel_time` int(11) NOT NULL,
`end_fuel_time` int(11) DEFAULT NULL,
`preset_amount` int(11) NOT NULL,
`actual_amount` int(11) DEFAULT NULL,
`fuel_cost` int(11) DEFAULT NULL,
`payment_cost` int(11) DEFAULT NULL,
`purchase_type` int(11) NOT NULL,
`payment_ref_id` text,
`unit_fuel_price` int(11) NOT NULL,
`fuel_status_id` int(11) DEFAULT NULL,
`fuel_mode_id` int(11) NOT NULL,
`payment_result` int(11) NOT NULL,
`card_pan` text,
`state` int(11) DEFAULT NULL,
`totalizer` int(11) NOT NULL DEFAULT '0',
`shift_start_time` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `terminal_transaction_id` (`terminal_transaction_id`,`fuel_terminal_id`,`start_fuel_time`) USING BTREE,
KEY `start_fuel_time_idx` (`start_fuel_time`),
KEY `fuel_terminal_idx` (`fuel_terminal_id`),
KEY `xboard_idx` (`xboard_id`),
KEY `gas_station_id` (`gas_station_id`) USING BTREE,
KEY `purchase_type` (`purchase_type`) USING BTREE,
KEY `shift_start_time` (`shift_start_time`) USING BTREE,
KEY `fuel_type` (`fuel_type`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1665335 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT
Merci pour votre temps,
OriginalL'auteur mOna | 2016-09-26
Vous devez vous connecter pour publier un commentaire.
MySQL peut raisonnablement effectuer des requêtes sur des milliards de lignes? -- MySQL peut "gérer" des milliards de lignes. "De manière raisonnable" dépend des requêtes; nous allons les voir.
Est InnoDB (MySQL 5.5.8) le bon choix pour plusieurs milliards de lignes? -- 5.7 a quelques améliorations, mais 5.5 est assez bonne, en dépit de l'
près de 6de 8 ans, et sur le point de ne plus être pris en charge.Meilleur magasin de données pour des milliards de lignes -- Si vous voulez dire "Moteur", alors InnoDB.
Grand comment une base de données MySQL obtenir avant la performance commence à se dégrader, Encore une fois, cela dépend des requêtes. Je peux vous montrer un 1K ligne de la table qui va effondrement; j'ai travaillé avec les milliards de rangée de tables fredonner.
Pourquoi MySQL peut être très lente avec des grandes tables? -- analyse de la plage conduire à des I/O, qui est la partie lente.
Peut gérer des tables Mysql qui pourra contenir environ 300 millions de disques? -- encore une fois, oui. La limite est quelque part autour d'un billion de lignes.
(pour les tables innoDB qui est mon cas) l'augmentation de la innodb_buffer_pool_size (par exemple, jusqu'à 80% de la RAM). Aussi, j'ai trouvé quelques autres performances MySQL modulable ici les paramètres dans percona blog -- oui
avoir un bon index sur la table (à l'aide de EXPLAN sur des requêtes) -- eh bien, nous allons voir. Il y a beaucoup d'erreurs qui peuvent être faites dans ce critique zone.
partitionnement de la table -- "le Partitionnement n'est pas une panacée!" Je la harpe sur que dans mon blog
MySQL Sharding -- Actuellement, c'est le BRICOLAGE
Cluster MySQL -- Actuellement, la meilleure réponse est de quelques Galera option (PXC, MariaDB 10, BRICOLAGE w/Oracle). Oracle du "Groupe de Réplication" est un concurrent viable.
De partitionnement ne prend pas en charge
FOREIGN KEY
ou "global"UNIQUE
.Uuid, à l'échelle que vous êtes en train de parler, ne sera pas seulement de ralentir le système, mais le fait de le tuer. Type 1 Uuid peut être une solution de contournement.
D'insertion et de construction d'index de vitesse -- Il y a trop de variations de donner une réponse unique. Voyons votre tentative
CREATE TABLE
et comment vous avez l'intention de nourrir les données dans la.Beaucoup de jointures -- "Normaliser, mais ne pas trop se normaliser." En particulier, ne pas normaliser datetimes flotteurs ou d'autres "en continu" des valeurs.
Faire construire résumé des tableaux
2,3 millions de transactions par jour, Si c'est de 2,3 M insère (30/sec), alors il n'y a pas beaucoup d'un problème de performance. Si en plus complexes, le RAID, SSD, dosage, etc, peuvent être nécessaires.
traiter un tel volume de données, Si la plupart de l'activité est avec la "récente" les lignes, puis les buffer_pool va bien "cache" pour l'activité et, ainsi, éviter les I/O. Si l'activité est "aléatoire", puis MySQL (ou personne d'autre) auront problèmes d'e/S.
Rétrécir les types de données permet dans un tableau similaire à la vôtre. Je doute si vous avez besoin de 4 octets pour spécifier
fuel_type
. Il y a plusieurs 1 octet approches.Merci Rick pour la réponse détaillée. Maintenant mon souci est que je ne suis pas sûr de savoir si nous devrions faire de clustering ou pas (je ne l'ai jamais fait avant). Je veux dire quand doit-on le faire et quand nous ne devrions pas? quels facteurs dois-je considérer avant de clustering? et si nous devons le faire, par où commencer?
Aussi, vous avez dit que vous devriez voir les requêtes (pour l'indexation, de la performance, ..). Quelles sont les informations sur les requêtes devrais-je envisager? quelles sont les informations à propos de notre application avez-vous besoin? Comment pourrais-je afficher les requêtes pour vous ? (désolé si il est question stupide!)
Type de données, les transferts d'argent? l'exploitation forestière? l'entreposage de données? la recherche scientifique lectures?
La taille n' pas indique une nécessité pour le partitionnement. L'activité d'écriture t indiquent un besoin de la fragmentation. HA (Haute Disponibilité) est un indicateur de "clustering". Plus de 100 lignes insérées/mis à jour par seconde indique de l'action, mais vous pouvez généralement obtenir à 1000/s sans fragmentation/clustering/etc. Massive "rapports", impliquant "group by" indique "tableaux de Synthèse". Etc.
OriginalL'auteur Rick James
Lors de la collecte des milliards de lignes, il est préférable (si possible) afin de rassembler, traiter, résumer, que ce soit, les données avant stockage. Conserver les données brutes dans un fichier si vous pensez que vous avez besoin pour obtenir dos.
Faire cela permettra d'éliminer la plupart de vos questions et préoccupations, en plus d'accélérer la vitesse de traitement.
OriginalL'auteur Rick James