Je travaille sur une application qui implique beaucoup d'écritures de base de données, environ 70% d'insertions et 30% de lectures. Ce ratio comprendrait également les mises à jour que je considère comme une lecture et une écriture. Grâce aux instructions d'insertion, plusieurs clients insèrent des données dans la base de données via l'instruction d'insertion ci-dessous:
$mysqli->prepare("INSERT INTO `track` (user, uniq_name, ad_name, ad_delay_time ) values (?, ?, ?, ?)");
La question est de savoir si j'utilise insert_delay ou le mécanisme mysqli_multi_query car l'instruction insert utilise ~ 100% de processeur sur le serveur. J'utilise le moteur InnoDB sur ma base de données, donc l'insertion différée n'est pas possible. L'insertion sur le serveur est ~ 36k / h et 99,89% de lecture, j'utilise également l'instruction select pour récupérer les données sept fois en une seule requête , cette requête prend 150 secondes sur le serveur pour s'exécuter. Quel type de technique ou de mécanisme puis-je utiliser pour cette tâche? La mémoire de mon serveur est de 2 Go, dois-je étendre la mémoire?. Jetez un oeil sur ce problème, toute suggestion me sera reconnaissante.
Structure de la table:
+-----------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user | varchar(100) | NO | | NULL | |
| uniq_name | varchar(200) | NO | | NULL | |
| ad_name | varchar(200) | NO | | NULL | |
| ad_delay_time | int(11) | NO | | NULL | |
| track_time | timestamp | NO | MUL | CURRENT_TIMESTAMP | |
+-----------------+--------------+------+-----+-------------------+----------------+
Ma base de données présente l'état, elle affiche 41 000 insertions (écritures), ce qui est très lent pour ma base de données.
SHOW FULL PROCESSLIST
quand il prend 100% de CPU? Combien de connexions autorisez-vous vs combien sont prises pendant cette période?SHOW GLOBAL VARIABLES LIKE 'innodb%';
etSELECT VERSION();
et afficher leur sortie.Réponses:
Puisque vous avez plus d'écrit puis de lecture, je voudrais recommander ce qui suit
Un réglage décent d'InnoDB serait la clé
Pool de tampons ( dimensionné par innodb_buffer_pool_size )
Comme InnoDB ne prend pas en charge INSERT DELAYED , l'utilisation d'un grand pool de tampons InnoDB est la chose la plus proche que vous pouvez obtenir pour INSERT DELAYED. Tous les DML (INSERT, UPDATE et DELETE) seraient mis en cache dans le pool de tampons InnoDB. Les informations transactionnelles pour les écritures sont écrites immédiatement dans les journaux de rétablissement (ib_logfile0, ib_logfile1). Les écritures qui sont publiées dans le pool de tampons sont périodiquement vidées de la mémoire sur le disque via ibdata1 (InsertBuffer pour les index secondaires, tampon d'écriture double). Plus le pool de tampons est grand, plus la quantité d'inserts peut être mise en cache. Dans un système avec 8 Go ou plus de RAM, utilisez 75 à 80% de la RAM comme taille innodb_buffer_pool_size. Dans un système avec très peu de RAM, 25% (pour accueillir l'OS).
CAVEAT: Vous pouvez définir innodb_doublewrite sur 0 pour accélérer encore plus les écritures, mais au risque d'intégrité des données. Vous pouvez également accélérer les choses en définissant innodb_flush_method sur O_DIRECT pour empêcher la mise en cache d'InnoDB sur le système d'exploitation.
Journaux de rétablissement ( dimensionnés par innodb_log_file_size )
Par défaut, les journaux de rétablissement sont nommés ib_logfile0 et ib_logfile1 et auraient 5 Mo chacun. La taille doit correspondre à 25% de la taille innodb_buffer_pool_size. Si les journaux de rétablissement existent déjà, ajoutez le nouveau paramètre dans my.cnf, arrêtez mysql, supprimez-les et redémarrez mysql .
Tampon de journal ( dimensionné par innodb_log_buffer_size )
Le tampon de journal contient les modifications de la RAM avant de les vider dans les journaux de rétablissement. La valeur par défaut est 8M. Plus la mémoire tampon du journal est grande, moins les E / S de disque sont importantes. Soyez prudent avec les transactions très importantes, car cela peut ralentir les COMMITs de quelques millisecondes.
Accès à plusieurs processeurs
MySQL 5.5 et le plug-in MySQL 5.1 InnoDB ont des paramètres permettant au moteur de stockage InnoDB d'accéder à plusieurs processeurs. Voici les options que vous devez définir:
Mettre à niveau vers MySQL 5.5
Si vous avez MySQL 5.0, passez à MySQL 5.5. Si vous avez MySQL 5.1.37 ou une version antérieure, passez à MySQL 5.5. Si vous avez MySQL 5.1.38 ou supérieur et que vous souhaitez rester dans MySQL 5.1, installez le plug-in InnoDB. De cette façon, vous pouvez profiter de tous les processeurs pour InnoDB.
la source
INT (2) utilise toujours 4 octets - peut-être que vous vouliez dire TINYINT UNSIGNED?
Combien de valeurs différentes dans setno? S'il est petit, la KEY (setno) ne sera jamais utilisée. INSERTing doit mettre à jour cet index; retirer la CLÉ accélérera EN INSÉRER.
CHAR (10) - La
flag
longueur est-elle toujours de 10 caractères? Et en utf8? Peut-être pourriez-vous utiliser le drapeau VARCHAR (10) CHARACTER SET asciiBatch vos inserts - 100 à la fois fonctionneront 10 fois plus vite. (Au-delà de 100 se met à «des rendements décroissants».)
Quelle est la valeur de l'autocommit? Enveloppez-vous chaque INSERT dans BEGIN ... COMMIT? Quelle est la valeur de innodb_flush_log_at_trx_commit?
la source
code
j'utilise : insérer dans les valeurs t_name (col1, col2, col3) (val1, val2, val3), (val1, val2, val3), (val1, val2, val3), (val1, val2, val3), (val1, val2, val3);code
Configurez une file d'attente. L'application écrirait dans une file d'attente 1 ligne à la fois, puis retirerait les lignes et les insérerait dans une base de données par lots en fonction du nombre de lignes ou du temps écoulé depuis la dernière insertion.
J'ai vu où le regroupement des inserts 10 000 à la fois est le plus rapide, vous devez donc tester pour trouver un point idéal.
Vous pouvez créer votre propre système de file d'attente simple ou utiliser un système existant. Voici quelques exemples: HornetQ et File :: Queue . Voici un article sur SE listant quelques autres bonnes options: Files d'attente de messages en perl, php, python .
la source