J'ai du mal à importer en masse une assez grande table InnoDB composée d'environ 10 millions de lignes (ou 7 Go) (qui est pour moi la plus grande table avec laquelle j'ai travaillé jusqu'à présent).
J'ai fait des recherches pour améliorer la vitesse d'importation d'Inno et pour l'instant ma configuration ressemble à ceci:
/etc/mysql/my.cnf/
[...]
innodb_buffer_pool_size = 7446915072 # ~90% of memory
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000
innodb_thread_concurrency=0
innodb_doublewrite = 0
innodb_log_file_size = 1G
log-bin = ""
innodb_autoinc_lock_mode = 2
innodb_flush_method = O_DIRECT
innodb_flush_log_at_trx_commit=2
innodb_buffer_pool_instances=8
import is done via bash script, here is the mysql code:
SET GLOBAL sync_binlog = 1;
SET sql_log_bin = 0;
SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;
SET AUTOCOMMIT = 0;
SET SESSION tx_isolation='READ-UNCOMMITTED';
LOAD DATA LOCAL INFILE '$filepath' INTO TABLE monster
COMMIT;
Les données sont fournies dans un CSV
fichier.
Actuellement, je teste mes paramètres avec de plus petits «vidages de test» avec 2 millions, 3 millions,… lignes chacun et j'utilise time import_script.sh
pour comparer les performances.
L'inconvénient est que je ne dispose que d'un temps de fonctionnement global, je dois donc attendre la fin de l'importation complète pour obtenir un résultat.
Mes résultats jusqu'à présent:
- 10000 lignes: <1 seconde
- 100 000 lignes: 10 secondes
- 300 000 lignes: 40 secondes
- 2 millions de lignes: 18 minutes
- 3 millions de lignes: 26 minutes
- 4 millions de lignes: (annulé après 2 heures)
Il semble qu'il n'y ait pas de solution de «livre de cuisine» et il faut trouver par lui-même la combinaison optimale de paramètres.
Outre des suggestions sur ce qu'il faut changer dans ma configuration, j'apprécierais également plus d'informations sur la manière de mieux évaluer le processus d'importation / d'avoir plus d'informations sur ce qui se passe et où se trouve le goulot d'étranglement.
J'ai essayé de lire la documentation des paramètres que je modifie, mais là encore je ne suis pas au courant d'effets secondaires et si je pouvais même diminuer les performances avec une valeur mal choisie.
Pour le moment, je voudrais essayer une suggestion de chat à utiliser MyISAM
lors de l'importation et changer le moteur de table par la suite.
J'aimerais essayer ceci mais pour le moment ma DROP TABLE
requête prend également des heures pour se terminer. (Ce qui semble être un autre indicateur que mon réglage est moins qu'optimal).
Informations supplémentaires:
La machine que j'utilise actuellement dispose de 8 Go de RAM et d'un disque dur hybride à semi-conducteurs avec 5400 tr / min.
Bien que nous cherchions également à supprimer les données obsolètes du tableau en question, j'ai encore besoin d'une importation assez rapide vers
a) le test automatic data cleanup feature
pendant le développement et
b) au cas où notre serveur se bloquerait, nous aimerions utiliser notre 2ème serveur comme remplacement (qui a besoin de plus de données à jour, la dernière importation a pris plus de 24 heures)
mysql> SHOW CREATE TABLE monster\G
*************************** 1. row ***************************
Table: monster
Create Table: CREATE TABLE `monster` (
`monster_id` int(11) NOT NULL AUTO_INCREMENT,
`ext_monster_id` int(11) NOT NULL DEFAULT '0',
`some_id` int(11) NOT NULL DEFAULT '0',
`email` varchar(250) NOT NULL,
`name` varchar(100) NOT NULL,
`address` varchar(100) NOT NULL,
`postcode` varchar(20) NOT NULL,
`city` varchar(100) NOT NULL,
`country` int(11) NOT NULL DEFAULT '0',
`address_hash` varchar(250) NOT NULL,
`lon` float(10,6) NOT NULL,
`lat` float(10,6) NOT NULL,
`ip_address` varchar(40) NOT NULL,
`cookie` int(11) NOT NULL DEFAULT '0',
`party_id` int(11) NOT NULL,
`status` int(11) NOT NULL DEFAULT '2',
`creation_date` datetime NOT NULL,
`someflag` tinyint(1) NOT NULL DEFAULT '0',
`someflag2` tinyint(4) NOT NULL,
`upload_id` int(11) NOT NULL DEFAULT '0',
`news1` tinyint(4) NOT NULL DEFAULT '0',
`news2` tinyint(4) NOT NULL,
`someother_id` int(11) NOT NULL DEFAULT '0',
`note` varchar(2500) NOT NULL,
`referer` text NOT NULL,
`subscription` int(11) DEFAULT '0',
`hash` varchar(32) DEFAULT NULL,
`thumbs1` int(11) NOT NULL DEFAULT '0',
`thumbs2` int(11) NOT NULL DEFAULT '0',
`thumbs3` int(11) NOT NULL DEFAULT '0',
`neighbours` tinyint(4) NOT NULL DEFAULT '0',
`relevance` int(11) NOT NULL,
PRIMARY KEY (`monster_id`),
KEY `party_id` (`party_id`),
KEY `creation_date` (`creation_date`),
KEY `email` (`email`(4)),
KEY `hash` (`hash`(8)),
KEY `address_hash` (`address_hash`(8)),
KEY `thumbs3` (`thumbs3`),
KEY `ext_monster_id` (`ext_monster_id`),
KEY `status` (`status`),
KEY `note` (`note`(4)),
KEY `postcode` (`postcode`),
KEY `some_id` (`some_id`),
KEY `cookie` (`cookie`),
KEY `party_id_2` (`party_id`,`status`)
) ENGINE=InnoDB AUTO_INCREMENT=13763891 DEFAULT CHARSET=utf8
SHOW CREATE TABLE yourtable\G
pour nous montrer la structure du tableau de ce tableau de 10 millions de lignes.
innodb_doublewrite = 0
), votre installation MySQL n'est pas protégée contre les pannes: si vous avez une panne de courant (pas une panne MySQL), vos données pourraient être silencieusement corrompues.