Nsg
jeudi 30 août 2007 à 18:28
Bonjour,
CITATION(bobdeo @ dimanche 19 août 2007 à 14:35)

J'ai un gros process de mise à jour d'un site. Il se décompose comme ceci :
- copie de gros fichiers XML sur le serveur (env 100 Mo au total)
- import des xml par un parsing avec php dans une table temporaire "pt_products_temp" --> dure 10 min
si ce n'est pas déjà fait essayes de passer directement du xml à une requête sql (ou un fichier cvs)
xml -> confrontation à un xsl ou dtd pour validation -> transformation xslt -> sortie sql ou texte
reste ensuite à donner directement la commande générée à mysql (ou faire un load data infile)
le tout placé dans un bash sh (éventuellement appelé par php ou cron)
il y a par exemple xsltproc comme processeur xml utilisable en ligne de commande (et donc via exec de php)
il faut bien sûr avoir les droit suffisant sur l'hébergement mais il y a de grande chance que xsltproc + "load data infile" aille plus vite que php/extention+requête ; et sur 10 minutes de traitement la différence peut être sensible. (maintenant si c'est à faire tous les 36 du mois à 3h du mat c'est peut-être pas la priorité)
CITATION
- on vide la table "pt_products" (table de production)
- on copie "pt_products_temp" dans "pt_products" --> dure quelques secondes
Mon code :
CODE
// on vide la table de prod
$sql = "TRUNCATE TABLE `pt_products`";
$resultat = mysql_query($sql);
// on copie les données
$sql = 'INSERT INTO `pt_products` SELECT * FROM `pt_products_temp`;';
$resultat = mysql_query($sql);
// on vide la table temp
$sql = "TRUNCATE TABLE `pt_products_temp`";
$resultat = mysql_query($sql);
il semble que TRUNCATE ne prenne pas en compte les transactions en cours, donc un LOCK serait adéquat (et peut être déjà en oeuvre)
et si un LOCK/UNLOCK est nécessaire, peut être que quelque secondes peuvent être gagnées en évitant le SELECT et en interchangeant les tables
après traitement dex xml > `pt_products_temp`:
CODE
LOCK TABLES `pt_products` WRITE, `pt_products_temp` WRITE`;
RENAME TABLE `pt_products` TO `pt_backup`,
`pt_products_temp` TO `pt_products`,
`pt_backup` TO `pt_products_temp`;
TRUNCATE `pt_products_temp`;
UNLOCK TABLES `pt_products`, `pt_products_temp`;
... à voir si le temps d'indisponibilité est plus court (temps total éventuellement plus long car le LOCK va attendre que les transactions en cours se terminent)
CITATION
Ca se passe plutôt bien sauf que des erreurs apparaissent en front :
CODE
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /home/sd/shopping/www/includes/database.php on line 21
Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/sd/shopping/www/includes/database.php on line 26
comme ça a été dit il y a un problème d'index après que la table ait été supprimée puis recrée avec TRUNCATE
après quelques recherche j'ai trouvé entre autres
ce post qui pourrait expliquer l'erreur sur certaines versions de mysql
il semble que ce soit une histoire d'index non "activés" à la recréation qui suit le TRUNCATE, ceci quand ces index ne sont pas PRIMARY ou UNIQUE
donc le MATCH qui nécessite un index ne fonctionne plus
la solution serait à priori de modifier tes index, car les réactiver avec ANALYSE ou OPTIMIZE TABLE tout de suite après le TRUNCATE ne fonctionnera sans doute pas ("table already up to date...") et le faire après l'insertion de toute les données prendra plus de temps (après un premier enregistrement ça devrait toutefois fonctionner)
là aussi c'est à tester...
il y a aussi la solution d'upgrader mysql
CITATION
Pourtant, un coup de "Réparer les table" dans PhpMyAdmin et c'est reparti...
Savez-vous pourquoi ? Existerait-il une solution plus fiable (en intervenant que sur le script d'import) ?
cf au dessus, la commande utilisée par le "Réparer les table" de PhpMyAdmin reconstruit les index entre-autres
A+
Nsg