[toulouse-pm] TPC (3)

Michel Rodriguez mrodrigu at ieee.org
Tue Jul 23 14:19:39 CDT 2002


Salut,

Bon, ben j'ai pas trop de compte-rendu pour l'apres-midi de lundi, vu que
plutot que d'aller voir Perl & XML (tres bien d'apres mon chef) j'ai
prefere rester a la terrasse de l'hotel a descendre des bieres avec les
francais du coing, Eric Cholet, qui bosse sur mod_perl, Antoine Quin,
qui faisait du SVG et du DOM dans son coin, Robin Berjon qui fait dans
le SAX et quelques XML-ers comme Matt Sergeant (54 modules sur CPAN la
derniere fois qu'il a compte).

Ce matin c'est Advanced DBI (je sais bien que je fais meme pas de Basic
DBI, mais si vous croyez que ca va m'arreter!).

C'est surtout sur "comment optimiser votre code pour qu'il aille le plus
vite possible". C'est Tim Bunce, l'auteur de DBI qui presente.

En vrac:

  - analyser les requetes avex EXPLAIN (ca depend de la DB)
  - utiliser des placeholders meme avec do
  - fetchrow_arrayref est la methode la plus rapide pour recuperer les
    resultats...
  - sauf que bind columns est encore plus rapide!
  - fetchall_arrayref a ete ameliore et est assez rapide maintenant
  - connect_cached peut etre utile pour cacher un DB handle (si on
    garde la connection toujours ouverte on peut avoir des pb si la
    DB est redemarree), sauf si on utilise des transactions.

Profiling: DBI::Profile permet de profiler du code DBI

Error Handling: les erreurs ca arrive, c'est de ne pas prevoir qu'elles
peuvent arriver qui les transforme en catastrophes.

Le plus rapide (et simple) pour traiter les erreurs d'apres lui:
Avoir RaiseError a 1 (qui fait un die si une erreur arrive), et
mettre le code qui utilise la db (plusieurs instructions donc) dans
un eval. Tester $@ apres le bloc, en cas d'erreur analyser le message
et utiliser les methodes DBI pour avoir plus d'info (il y a une
nouvelle facon de recuperer l'instruction qui a plante mais j'ai pas
eu le temps de la lire :--(
Une autre facon de faire c'est d'utiliser HandleError:
$h->{Handle::Error}= sub toto (le handler peut meme faire un reset de
l'erreur si on veut l'ignorer)

Transactions

Un petit coup sur MySQL qui jusqu'a il n'y a pas longtemps pretendait
qu'il n'y a pas besoin de transactions, jusqu'a qu'ils les ajoutent a
la DB ;--) Monty ne repond pas.

Comment faire des transactions avec DBI:
$dbh->begin_work commence un transaction ($dbh->commit pour la terminer)

Apres la pause:

Un apercu de l'architecture de DBI. Tim conseille d'utiliser les fonctions
de trace ($h->{TraceLevel}= $level; ou la variable d'environnement
DBI_TRACE
dans laquelle on peut mettre un nom de fichier qui recevra la trace) pour
resoudre les problemes. Je vous passe le detail des differents niveaux de
trace, la doc est la pour ca (perldoc DBI et chercher DEBUGGING).

DBI pur le web:

D'abord les conseils classiques: utiliser mod_perl et Apache::DBI qui
accelere le code de maniere transparente.
Un conseil pratique: comme le handler reste en vie entre les transactions,
ne pas le modifier (du genre jouer avec auto commit).

Si vous avez enormement d'acces a la DB, utiliser un proxy sur les scripts
qui accedent a la DB, sur une machine dediee par exampe.

Problemes dus au fait que le Web ne garde pas l'etat (il est stateless
quoi):
utiliser des hidden fields (facile mais pas sur), Apache::Session peut
aider
aussi.

Browser une DB page par page: refaire la query et jeter les records
inutiles,
facile a faire, surtout que MySQL par exemple supporte ca assez bien. Un
inconvenient est que les insert/delete ne sont pas bien traites. Une autre
solution est de stocker les resultats de la query la premiere fois et de
ne renvoyer que les resultats voulus. C'est mieux de ne stocker ques les
ID (tous) et d'aller chercher les records voulus (rapidement a l'aide de
la key) Beaucoup de DB ont un pseudo champ ROWID, avec MySQL _ROWID
retourne la primary key d'un record quel qu'il soit.

Securite: UTILISER -T (taint mode). Si vous ecrivez quoi que ce soit pour
le web (ou accessible par des utilisateurs auxquels vous ne faites pas
confiance) et que vous ne connaissez pas -t, RENSEIGNEZ-VOUS! perldoc
perlsec est un bon debut.

Traitement des BLOBs: DBI se debrouille bien, il manque juste des
fonctions
pour decouper les BLOBs et les traiter morceau par morceau. Si vous en
avez
besoin vous pouvez emailer Tim pour faire monter la pression ;--)

Portabilite: SQL a plein de dialectes, dans le langage, dans les types de
champs et dans les fonctionalites des drivers (DBD) Il manque une test
suite unique pour tester les fonctionalites des drivers (volontaires
bienvenus!).

On peut utiliser la methode type_info pour recuperer le type exact d'un
champ dans une DB et choisir le meilleur type equivalent dans une autre.

Curieusement une des fonctions qui varie le plus entre DBs est la
concatenation de chaines de caracteres (CONCAT, avec differentes syntaxes,
'.', '-'...). Il y aura bientot une methode dans DBI qui fera ca de
maniere
portable. Bien sur les drivers devront etre mis-a-jour aussi remarque
Monty
(reponse de Tim: "ca arrivera naturellement").

Citation du jour: "DBI has taken over the World" Tim explique qu'il n'y a
vraiment aucune raison d'utiliser OBDC, DBI est plus rapide et couvre
toutes les fonctionalites d'OBDC.

DBI::Proxy et DBI::ProxyServer permettent de contacter a distance
des DBs qui ne supportent pas les connections a distance. C'est
completement transparent, il suffit de changer une variable
d'environnement (dont j'ai rate le nom, darn! Eric? (Cholet,
assis 3 rangees devant moi, qui doit suivre au lieu de taper le CR
en direct)
Le proxy supporte aussi l'encryptage des donnees,la compression,
et faire du controle d'acces. Kewl!

DBI::PurePerl peut etre utile sur des plateforme sans compilateur. Il
faut bien sur avoir des DBDs (et autres modules en pur Perl): AnyData
(excellent DBD pour des fichiers textes et autres), LDAP, mysqlPP je
crois etc...

La variable d'environement DBI_PUREPERL (je fais attention maintenant)
permet d'activer ce mode (c'est juste 2x plus lent que la version C,
ce qui reste rapide).

Nouvelles methodes selectrow_hashref, fetchall_arrayref,
select_all_hasref,
fetchall_hasref, $h->{FetchHashReuse}=1 ameliore la vitesse de
fetchrow_hasref
(non encore implemente), voir la doc...

Prevu dans un futur proche: nouvelle FAQ, vitesse, swap_internal_handle
fait une "greffe de cerveau a un DB handle", me demandez pas de details!
Renommer finish() en close()
scroll permet de se deplacer dans les resultats, sans les lire forcement
dans l'order).
execute_array: une methode qui permet de faire des operations par lots,
execute est execute pour les valeurs dans le tableau (de references a des
tableaux)

Autres

Plus de compte-rendus sur use.perl.org (regarder les 'journals', notament
celui de gnat (Nat Torkington, il organise la conference donc il devrait
etre au courant), et a http://www.oreillynet.com/weblogs/author/945.
Photos par Leon a http://www.astray.com/photos/?search=tpc6 (les miennes
arrivent ce soir).


A tschao

Michel Rodriguez
Perl & XML
http://www.xmltwig.com






More information about the Toulouse-pm mailing list