Insertion InnoDB plus rapide

8

Je suis un étudiant diplômé de recherche OLAP avec Mondrian OLAP. Je veux donc insérer des données dans InnoDB (MySQL 5.5) plus rapidement lors du chargement initial. Dans cet environnement, le seul utilisateur est moi, donc je pense que je peux autoriser des paramètres plus lâches pour la vitesse d'insertion. Pour le moment, j'utilise les techniques suivantes.

  • désactiver log_bin
  • activer skip-innodb-doublewrite
  • réglé transaction_isolationsur READ-COMMITTEDou READ-UNCOMMITTED(en fait READ-COMMITED)
  • réglé innodb_flush_log_at_trx_commitsur 0ou 2(en fait 0)
  • réglé innodb_buffer_pool_sizesur 5 Go (le système a 6 Go de RAM)

Existe-t-il d'autres techniques pour une insertion plus rapide sur InnoDB? Et dois-je modifier innodb_io_read_threadet innodb_io_write_thread? Si vous avez besoin de plus d'informations, dites-le moi.

inohiro
la source

Réponses:

9

SUGGESTION # 1

Si votre machine possède plusieurs cœurs, vous devez augmenter les éléments suivants:

[mysqld]
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000

Qu'est-ce que c'est?

  • innodb_read_io_threads - Le nombre de threads d'E / S pour les opérations de lecture dans InnoDB.
  • innodb_write_io_threads - Le nombre de threads d'E / S pour les opérations d'écriture dans InnoDB.
  • innodb_io_capacity - Une limite supérieure sur l'activité d'E / S effectuée par les tâches d'arrière-plan InnoDB, telles que le vidage des pages du pool de tampons et la fusion des données du tampon d'insertion.

SUGGESTION # 2

Pour séparer les données et les index du tablespace système (ibdata1), vous devez effectuer une restructuration complète d'InnoDB. Cela semble compliqué, mais c'est très simple. J'ai écrit à ce sujet dans le DBA StackExchange (29 août 2012) et dans StackOverflow (29 octobre 2010) . Les étapes de base sont

  • Courir SET GLOBAL innodb_fast_shutdown = 0;
  • mysqldump toutes les données dans un vidage SQL
  • service mysql stop
  • Supprimez les fichiers suivants
    • ibdata1
    • ib_logfile0
    • ib_logfile1
  • service mysql start

Avant d'exécuter service mysql start, ajoutez cette ligne àmy.cnf

innodb_open_files=32768

De cette façon, il y aura des descripteurs de fichiers dédiés à chaque table individuelle. La valeur par défaut est 300. Les descripteurs de fichiers sont connus pour être mis en cache. Il y aura un ralentissement si vous réglez cette valeur très haut et atteignez rapidement le plafond . Cela ne devrait pas être le cas si vous travaillez sur un petit nombre de tables.

RolandoMySQLDBA
la source
Merci pour vos suggestions. Je vais essayer de suggestion # 2 en ce moment, et je vais régler innodb_read_io_threads, innodb_write_io_threadset `innodb_io_capacity ».
inohiro
"Supprimez les fichiers suivants ibdata1" Sheesh, sans avertissement.
magallanes
6

Il existe un document entier dédié au chargement en masse des données dans InnoDB. Les points principaux:

  1. désactivez la validation automatique pour éviter un vidage de journal supplémentaire pour chaque instruction d'insertion: SET autocommit=0;...sql import;COMMIT;
  2. désactiver les contrôles étrangers et uniques (vous ne pouvez pas désactiver complètement tous les index):

    SET unique_checks=0;
    SET foreign_key_checks=0;
  3. Définissez potentiellement innodb_autoinc_lock_mode sur 2, au lieu de 1 (valeur par défaut). Voici la documentation sur ce paramètre.

Le troisième peut ou non vous aider, je vous suggère donc de lire ce lien pour voir comment vous chargez initialement les données. Par exemple, si vous divisez les charges en plusieurs insertions pour qu'elles s'exécutent simultanément, cela vous aidera certainement à définir la valeur sur 2. Si vous effectuez une grande insertion multi-lignes, cela ne fera pas grand-chose (le cas échéant) pour Aidez-moi.

Puisque vous désactivez le journal binaire pour cette insertion initiale, vous ne devez pas vous soucier des lacunes dans les nombres d'auto-incrémentation (si vous effectuez des insertions simultanées).

Derek Downey
la source
Merci pour votre réponse! L'insert en vrac semble si rapide, et je l'essayerai plus tard.
inohiro
La simple définition de autocommit = 0 a été augmentée par des ordres de grandeur. Merci!
Alex Barker
1

Vous pouvez utiliser les méthodes suivantes pour accélérer les insertions:

  • Si vous insérez plusieurs lignes du même client en même temps, utilisez des INSERTinstructions avec plusieurs VALUESlistes pour insérer plusieurs lignes à la fois. Ceci est considérablement plus rapide (plusieurs fois plus rapide dans certains cas) que l'utilisation d' INSERTinstructions séparées sur une seule ligne . Si vous ajoutez des données à une table non vide, vous pouvez régler la variable bulk_insert_buffer_size pour accélérer l'insertion des données.
  • Lors du chargement d'un tableau à partir d'un fichier texte, utilisez LOAD DATA INFILE. Ceci est généralement 20 fois plus rapide que l'utilisation d' INSERTinstructions. Voir
  • Profitez du fait que les colonnes ont des valeurs par défaut. Insérez des valeurs explicitement uniquement lorsque la valeur à insérer diffère de la valeur par défaut. Cela réduit l'analyse que MySQL doit effectuer et améliore la vitesse d'insertion.
  • Voir Section 9.5.5, « Chargement de données en masse pour les tables InnoDB » pour des conseils spécifiques aux tables InnoDB.
user2432735
la source
0

Plan A: INSERT "en lot" - plusieurs lignes par instruction INSERT. Suggérez environ 1000 lignes par instruction. autocommit = on, pas de COMMENCEMENT explicite ... COMMIT

Plan B: CHARGER LES DONNÉES

Si vous insérez trop de lignes à la fois, InnoDB doit faire plus de travail pour pouvoir annuler l'insertion en cas de plantage. Pour cette raison, je suis en désaccord avec autocommit = off, qui mettrait l'ensemble entier en une seule transaction.

LOAD DATA de l'ensemble des lignes pourrait avoir le même problème, mais c'est assez rapide.

buffer_pool = 5G sur 6G est sur le point d'être trop gros. S'il y a un échange, les performances chuteront.

Le partitionnement ralentirait probablement le processus.

AFFICHER CRÉER UN TABLEAU - Les clés secondaires peuvent être un sérieux handicap.

Utilisez-vous InnoDB? ou XtraDB?

Rick James
la source
Merci pour votre réponse. J'utilise InnoDB. Je préfère que le plan A au plan B. LOAD DATAsoit si rapide, mais nous devons écrire des données sur du texte en même temps au format CSV, puis les utiliser LOAD DATA? / Je vais régler le buffer_pool_sizeà 4 Go.
inohiro