Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

optimisation Accès mySQL

9 réponses
Avatar
paul
Bonjour,

dans le cadre du projet koha (www.koha-fr.org), codé en Perl, j'essaye
d'améliorer la moulinette qui fait des imports en masse (codée en Perl
ligne de commande, pas en CGI).
Actuellement, elle n'importe guère plus de 8-9 notices à la seconde. quand
il s'agit de faire un import de 50 000...

Donc, j'ai :
- tuné mySQL avec des caches hénaurmes[1].
- ajouté des $dbh->do("lock tables X write") avant l'appel de mes fonctions
qui fonc les ajouts.
- changé les insert en insert delayed.

mais j'ai pas vraiment d'amélioration des perfs.

donc questions :
- le "lock tables write" bloque les tables dans le thread mySQL courant. Un
programme Perl utilisera ce seul thread là tant qu'on ne se déconnecte pas
? Quelqu'un peut confirmer ?
- Y a t'il une autre manière d'accélerer la moulinette. Un top montre que
c'est plus du coté mySQL que ca rame que du coté Perl, mais si un champion
du Perl a une suggestion...

PS : à priori, les tables sont indexées correctement et tous les accès sont
indexés. enfin, je crois ;-)

[1]
[root@bureau paul]# cat /etc/my.cnf
[mysqld]
set-variable = key_buffer=16M
set-variable = max_allowed_packet=1M
set-variable = table_cache=128
set-variable = sort_buffer=4M
set-variable = record_buffer=1M
--
Paul

9 réponses

Avatar
Manganneau Emmanuel
le Wed, 03 Sep 2003 18:44:32 +0200, paul
a ecrit:

Bonjour,


Bonjour,


dans le cadre du projet koha (www.koha-fr.org), codé en Perl, j'essaye

d'améliorer la moulinette qui fait des imports en masse (codée en Perl

ligne de commande, pas en CGI).
Actuellement, elle n'importe guère plus de 8-9 notices à la seconde.
quand il s'agit de faire un import de 50 000...

Donc, j'ai :
- tuné mySQL avec des caches hénaurmes[1].
- ajouté des $dbh->do("lock tables X write") avant l'appel de mes
fonctions qui fonc les ajouts.
- changé les insert en insert delayed.

mais j'ai pas vraiment d'amélioration des perfs.


[...snip...]

PS : à priori, les tables sont indexées correctement et tous les acc ès
sont indexés. enfin, je crois ;-)


Ne voyant pas le sql ni le code perl, ca va pas etre facile...
Cependant, si les tables sont indexées, c'est une perte de perf.

Pour les inserts massifs :
- faire les select necessaires aux insertions et les stocker en RAM
(varibles perl)
- construire les requetes
- *supprimer* les index !
- faire les inserts en minimisant les controles faits par la base
(préférez les faire dans le script)
- reconstruire les index

On peut gagner d'un facteur superieur à 10 dans certains cas par rapport
à l'insert basique.
HTH,

--
| Manganneau Emmanuel | GestraNet SARL |
| | tel : 06 64 09 73 07 |
`--------------------------------------------------------'

Avatar
paul
Alain BARBET wrote:

Pourquoi poster sur Perl ce qu'il me semble être de la config Mysql ?

mais si un champion du Perl a une suggestion...


Bon champion c'est prétentieux, mais pour être sur que du coté Perl tu
ne peux rien faire, commence par un bench:

perldoc Devel::DProf

Tu verras bien où se passe le temps.

Ensuite pour ta config mysql tu aurais plus de succès sur un news
adéquat style fr.comp.applications.sgbd.


La config mySQL, je crois en avoir fait mon affaire. Mais je vais quand même
poser la question sur fcas.

mysql> LOCK TABLES a WRITE;
mysql> INSERT INTO a VALUES (1,23),(2,34),(4,33);
mysql> INSERT INTO a VALUES (8,26),(6,29);
mysql> UNLOCK TABLES;
J'ai essayé ca, mais ca ne change rien.

C'est la raison de ma question ici : est-ce que Perl n'utilise bien qu'un
thread à partir du moment ou on n'ouvre qu'un $dbh et qu'on fait toutes les
opérations $dbh->do("insert...") dessus ?
Parce que si Perl change de thread, évidemment, ca unlocke les tables, et le
lock ne sert à rien.

- changé les insert en insert delayed.
Utile dans ton cas ?



non.
La seule chose "un peu" efficace, c'est de dropper tous les index, et de les
reconstruire après (on gagne 15% environ, mais rien de foudroyant)
--
Paul


Avatar
Laurent Wacrenier
Manganneau Emmanuel écrit:
Pour les inserts massifs :
- faire les select necessaires aux insertions et les stocker en RAM
(varibles perl)
- construire les requetes
- *supprimer* les index !
- faire les inserts en minimisant les controles faits par la base
(préférez les faire dans le script)
- reconstruire les index


Détruire les index n'est pas interessant si la quantité de lignes
n'est pas importante vis à vis des lignes indexées.

Avatar
Emmanuel Florac
Dans article , Laurent Wacrenier
<lwa@ teaser . fr> disait...

Détruire les index n'est pas interessant si la quantité de lignes
n'est pas importante vis à vis des lignes indexées.


Une bonne solution est de forcer l'utilisation d'InnoDB et de faire
l'insert dans une transaction. De toute façon utiliser un moteur qui ne
sait pas faire de transactions (MySQL 3.xx, qui ne mérite de fait pas le
nom de SGBDR) est une grosse connerie pas vrai?

--
Quis, quid, ubi, quibus auxiliis, cur, quomodo, quando?

Avatar
Manganneau Emmanuel
le Thu, 04 Sep 2003 09:57:56 +0200, paul
a ecrit:

Pour les inserts massifs :
- faire les select necessaires aux insertions et les stocker en RAM
(varibles perl)
- construire les requetes
- *supprimer* les index !
- faire les inserts en minimisant les controles faits par la base
(préférez les faire dans le script)
- reconstruire les index

On peut gagner d'un facteur superieur à 10 dans certains cas par
rapport à l'insert basique.


Quelques explications complémentaires :
Le script d'import de notices bibliographiques dans Koha (logiciel de
gestion de bibliothèques) utilise la fonction standard de création
d'une notice.
Habituellement, les notices sont créées 1 par 1, et les perfs ne sont
pas un problème.
Créer une notice (dans Koha), c'est faire des inserts dans 6 tables
différentes, avec 1 à X lignes dans chaque table (tables d'index...)
Le tout en vérifiant la cohérence de certaines données dans d'autre s
tables...


Aie : c'est typiquement ce que j'aurais essayer de déporter dans le code


Bref, impossible, à moins de reprendre complètement une fonction de
création spécialisée dans l'import massif, impossible disai-je
d'utiliser les suggestions 1,2,4 ci-dessus.
Seule la suggestion "supprimer les index" est envisageable. J'ai
essayé rapidement. Ca améliore encore "un peu". Mais pas dans un
facteur 10. Environ 15-20%.


C'est l'ensemble qui permet de gros gain, notamment éviter de faire des
selects avant chaque insert

Cela dit, vu que ce genre d'insertion massive ne se fait qu'une fois
lors de la migration de données d'un ancien système vers Koha, je vais
peut être laisser en l'état, avec mes 7-8 notices par seconde.


Oui, en gros ca fait moins de 3h et ce qu'on demande à une mig c'est
d'etre < 1 jour (le samedi pour pouvoir corriger le dimanche :))

PS :
Notez que c'est sur un disque IDE. Ca irait surement plus vite sur un
SCSI.


probable, mais pas d'incidence sur les tables mappées en mémoire

Notez enfin qu'une proc sto pourrait faire ca plus vite que Perl
si mySQL savait gérer les proc sto :-(


pas forcément, voire loin de là ! Rien ne vaut un code spécifique, en
perl ou en C (quasi aussi rapides)

--
Paul



--
| Manganneau Emmanuel | GestraNet SARL |
| | tel : 06 64 09 73 07 |
`--------------------------------------------------------'


Avatar
paul
Emmanuel Florac wrote:

Dans article , Laurent Wacrenier
<lwa@ teaser . fr> disait...

Détruire les index n'est pas interessant si la quantité de lignes
n'est pas importante vis à vis des lignes indexées.


Une bonne solution est de forcer l'utilisation d'InnoDB et de faire
l'insert dans une transaction. De toute façon utiliser un moteur qui ne
sait pas faire de transactions (MySQL 3.xx, qui ne mérite de fait pas le
nom de SGBDR) est une grosse connerie pas vrai?
mySQL ne mérite pas le nom de SGBDR, c'est vrai. Aussi pour la version 4,

même si on progresse.
Utiliser mySQL est une grosse connerie... Je suis plus mesuré, vu que
j'utilisé :-) Mais il est vrai que j'ai préféré firebird pour plein de
raisons (sauf pour les pb de proc sto mises en cache, qui nécessitent
service restart lorsqu'on les modifie, sinon => big risque de corruption de
la base...)

Mais bon, on est HS et ca va droit dans le troll :-)
--
Paul


Avatar
Emmanuel Florac
Le Thu, 04 Sep 2003 17:14:25 +0200, paul écrivait:

mySQL ne mérite pas le nom de SGBDR, c'est vrai. Aussi pour la version 4,
même si on progresse.


On y est presque :)

Utiliser mySQL est une grosse connerie... Je suis plus mesuré, vu que
j'utilisé :-)


Moi aussi et pire, je continue :)

Mais il est vrai que j'ai préféré firebird pour plein de
raisons (sauf pour les pb de proc sto mises en cache, qui nécessitent
service restart lorsqu'on les modifie, sinon => big risque de corruption de
la base...)


Il faudrait que j'essaie, et postgres aussi.

--
Ne pas savoir de quoi on parle est un avantage dont il ne faut
pas abuser.
R.Debray

Avatar
paul
Emmanuel Florac wrote:
Mais il est vrai que j'ai préféré firebird pour plein de
raisons (sauf pour les pb de proc sto mises en cache, qui nécessitent
service restart lorsqu'on les modifie, sinon => big risque de corruption
de la base...)


Il faudrait que j'essaie, et postgres aussi.
Mon expérience de Firebird :

- outil stable, sauf dans 1 cas que je reprendrai plus loin.
- tout ce dont on a besoin dans un SGBDR (proc sto, transations,
contraintes...)
- support utilisateur assez limité.
- outils type phpmyadmin assez rudimentaires en libre. Un excellent outil
propriétaire et payant sous winmachin (j'ai perdu le nom... Un truc fait
par des russes, ou des ukrainiens si je me souviens bien)
- GROS problème que j'ai mis du temps à comprendre : la structure de la base
est mise en cache. Lorsqu'on modifie une table, l'ancienne structure peut
être "oubliée" dans le cache, d'ou grosse corruption des données si on fait
des inserts... On a perdu 3-4 fois la base en faisant ca. Heureusement,
c'était pendant la phase dev. (la phase prod, ya pas eu longtemps : mon
employeur a fait faillite trop vite :-) )
- en théorie, possibilité de rajouter des fonctions au SQL standard, mais on
n'a jamais réussi à faire un truc stable. Plantages au bout de quelques
minutes/heures de travail.
- performances n'ayant pas trop à envier à mySQL.

Bref, des bonnes choses.

Je précise que c'était il y a 2 ans / 18 mois. donc des choses ont peut être
changé depuis.
--
Paul


Avatar
Emmanuel Florac
Dans article <bj7u0b$1otb$,
disait...

- GROS problème que j'ai mis du temps à comprendre : la structure de la base
est mise en cache. Lorsqu'on modifie une table, l'ancienne structure peut
être "oubliée" dans le cache, d'ou grosse corruption des données si on fait
des inserts...


Ca j'arrive pas bien à saisir... Qu'est ce qu'il faut faire, arrêter et
redémarrer le service, c'est ça?

--
Quis, quid, ubi, quibus auxiliis, cur, quomodo, quando?