2010-02-05 4 views
1

Contexte:incrémenter d'insertion de données dans mySQL Plus lent

Nous avons de gros fichiers plats enjambent autour de 60 Go et insérez dans la base de données. Nous subissons une dégradation progressive des performances lors de l'insertion.

  • Nous avons 174 (millions) dossiers et d'attendre une autre 50 (millions) à insérer
  • Nous avons fente table principale en 1000 tables sur la base des premiers-deux caractères de nom d'entité par exemple entity_aa, entity_ab ... entity_zz
  • Lors de chaque insertion, il y a trois requêtes: (a) recherche par plage dans une autre table, (b) vérification si l'enregistrement est déjà inséré ou non (c) insertion dans le détail (entity_briefs)
  • Nous avons ajouté entity_briefs pour traiter les requêtes de recherche fréquentes, mais nous avons réalisé que, lors de l'insertion dans la base de données, il ralentit graduellement peu importe si nous ALTER TABLE entité (ou entity_briefs) DISABLE (ou ENABLE) KEY.
  • La machine dispose de 4 processeurs, Gigs d'espace disque, 2 Go de RAM. Système d'exploitation est Linux CentOS (5.4) 32bit
  • Nous avons constaté que tous les 4 processeurs sont obtenir utilisés
  • Nous avons couru 4 scripts d'importation à la fois, quoique la performance globale est pas satisfaisante

Problématiques Tableau

CREATE TABLE `entity_briefs` (
`entity_brief_id` bigint(11) NOT NULL auto_increment, 
`entity_id` bigint(11) default NULL, 
`entity_table_prefix` char(2) default NULL, 
`string_1` varchar(255) default NULL, 
`string_2` varchar(255) default NULL, 
`zip` varchar(25) default NULL, 
`phone` bigint(11) default NULL, 
PRIMARY KEY (`entity_brief_id`), 
KEY `idx_entity_id` (`entity_id`), 
KEY `idx_entity_table_prefix` (`entity_table_prefix`), 
KEY `idx_zip` (`zip`), 
KEY `idx_string_1` (`string_1`), 
KEY `idx_string_2` (`string_2`), 
KEY `idx_phone` (`phone`) 
); 

sortie mysqltuner.pl:

>> MySQLTuner 1.1.1 - Major Hayden <[email protected]> 
>> Bug reports, feature requests, and downloads at http://mysqltuner.com/ 
>> Run with '--help' for additional options and output filtering 
Please enter your MySQL administrative login: xxxxx 
Please enter your MySQL administrative password:xxxxx 

-------- General Statistics -------------------------------------------------- 
[--] Skipped version check for MySQLTuner script 
[OK] Currently running supported MySQL version 5.0.85-community 
[OK] Operating on 32-bit architecture with less than 2GB RAM 

-------- Storage Engine Statistics ------------------------------------------- 
[--] Status: +Archive -BDB -Federated +InnoDB -ISAM -NDBCluster 
[--] Data in MyISAM tables: 101M (Tables: 1344) 
[!!] InnoDB is enabled but isn't being used 
[!!] Total fragmented tables: 1 

-------- Security Recommendations ------------------------------------------- 
ERROR 1142 (42000) at line 1: SELECT command denied to user 'xxxx'@'localhost' for table 'user' 
[OK] All database users have passwords assigned 

-------- Performance Metrics ------------------------------------------------- 
[--] Up for: 5d 15h 53m 55s (2M q [4.395 qps], 9K conn, TX: 1B, RX: 425M) 
[--] Reads/Writes: 51%/49% 
[--] Total buffers: 34.0M global + 2.7M per thread (500 max threads) 
[OK] Maximum possible memory usage: 1.3G (67% of installed RAM) 
[OK] Slow queries: 0% (9/2M) 
[OK] Highest usage of available connections: 1% (5/500) 
[!!] Key buffer size/total MyISAM indexes: 8.0M/105.3M 
[!!] Key buffer hit rate: 94.1% (72M cached/4M reads) 
[!!] Query cache is disabled 
[OK] Temporary tables created on disk: 7% (101 on disk/1K total) 
[!!] Thread cache is disabled 
[!!] Table cache hit rate: 0% (64 open/277K opened) 
[OK] Open file limit used: 0% (127/18K) 
[OK] Table locks acquired immediately: 99% (2M immediate/2M locks) 
[!!] Connections aborted: 38% 

-------- Recommendations ----------------------------------------------------- 
General recommendations: 
    Add skip-innodb to MySQL configuration to disable InnoDB 
    Run OPTIMIZE TABLE to defragment tables for better performance 
    Enable the slow query log to troubleshoot bad queries 
    Set thread_cache_size to 4 as a starting value 
    Increase table_cache gradually to avoid file descriptor limits 
    Your applications are not closing MySQL connections properly 
Variables to adjust: 
    key_buffer_size (> 105.3M) 
    query_cache_size (>= 8M) 
    thread_cache_size (start at 4) 
    table_cache (> 64) 

Condition: Afin d'accélérer l'insertion, quelle stratégie d'optimisation peut-on utiliser?

Répondre

3

Quelques suggestions générales, comme je n'ai pas une balle d'argent pour vous:

Je ne pense pas que vous pouvez attendre que les choses à ne pas ralentir du tout à l'insertion comme la taille de la table se développent. Les temps d'insertion de la base de données seront généralement proportionnels à la taille de la base de données, l'astuce consiste à essayer de rendre la performance globale acceptable compte tenu de cette attente.

Si les choses ralentissent et que la CPU n'est pas bloquée, vous êtes probablement lié aux E/S lors de l'accès à la base de données. Si vous trouvez que c'est le cas, vous pouvez essayer des disques plus rapides, RAID 0, des contrôleurs de disque plus rapides, etc. Vous pouvez même envisager de construire la base de données sur un disque SSD puis de le copier après la création conduire. Ceux-ci devraient être beaucoup plus rapides pour le comportement d'accès aléatoire que vous pouvez attendre de mysql sur un système de fichiers, même si je comprends que vous les 'userez' au fil du temps. Pourtant, vous pouvez obtenir un téraoctet de stockage à l'état solide sous 10k $.

Jetez également un coup d'œil à l'optimisation de votre procédure d'insertion. La désactivation des index pendant les insertions comme vous le mentionnez, même si elle n'arrêtera pas le ralentissement progressif, devrait accélérer considérablement la procédure globale. Je prends de votre description que vous avez une sorte de logique de script d'insertion qui sélectionne et insère, pas une simple CHARGE d'un fichier plat. Vous effectuez trois requêtes différentes par insertion, en arrondissant éventuellement les données plusieurs fois entre votre client et la base de données. Examinez particulièrement cette sélection à intervalle et assurez-vous que cette requête n'a pas de mauvaises caractéristiques de performance sur la taille de la table.Une autre possibilité peut être de lancer beaucoup plus de RAM sur le problème et de l'utiliser comme cache de disque. Si cette "autre table" que vous utilisez n'est pas modifiée pendant votre insertfest, vous pouvez peut-être l'obtenir en mémoire pour réduire la recherche de lecteurs, si vous déterminez que le temps de recherche est bien lié aux performances ici.

+0

Salut bdk, merci pour la recommandation complète. J'aimerais pouvoir vous donner 10 points :) – r0ash