Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3016 connectés 

  FORUM HardWare.fr
  Programmation
  PHP

  Aide pour optimiser mon code => insert bdd

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Aide pour optimiser mon code => insert bdd

n°1653743
hornetmen
GaZZzz... Et Flash....22
Posté le 06-12-2007 à 12:39:56  profilanswer
 

Bonjour,
J'ai un probleme de temps de traitement.
 
Le perimetre :
1 fichier de 4MO typé CSV (',').
Chaque ligne de ce fichier est à insérer dans une base Mysql.
 
La problématique :
Pour chaque enregistrement (chaque ligne), je dois tester la présence de chaque éléments dans la base avant de l'insérer (5 requetes pa ligne).
 
Le souhait:
Paralléliser les tests de présence dans la base par lot de ligne.
 
Genre:
Je lis 100 lignes => execute pour chaque ligne une fonction (en mode simultané, pas 1 par 1).
 
Environnement:
Je lis mon fichier ligne par ligne avec fgetcsv.
 
 
Avez vous des idées ?


Message édité par hornetmen le 06-12-2007 à 17:16:43
mood
Publicité
Posté le 06-12-2007 à 12:39:56  profilanswer
 

n°1653776
anapajari
s/travail/glanding on hfr/gs;
Posté le 06-12-2007 à 13:18:32  profilanswer
 

tu créés une table temporaire ( keyword: temporary) en pensant aux indexs nécessaires.
Tu fais un load data infile dans la dite table de ton fichier csv.
Tu fais tes requêtes de comparaison entre ta table temporaire et ta table destination, puis les insertions.

n°1653844
hornetmen
GaZZzz... Et Flash....22
Posté le 06-12-2007 à 14:25:57  profilanswer
 

Oui c'est une solution.
Mais je souhaite etudier l'idée de requetage // à partir des lignes dans mon fichier ;)

n°1653848
anapajari
s/travail/glanding on hfr/gs;
Posté le 06-12-2007 à 14:32:49  profilanswer
 

bin fais comme tu veux ... [:spamafote]
Mais ensuite tu vas te rendre compte que c'est lent, lourd et qu'il va falloir le refaire correctement :o

n°1653857
hornetmen
GaZZzz... Et Flash....22
Posté le 06-12-2007 à 14:40:34  profilanswer
 

Ok,
 
Le soucy c'est que j'ai 4 tables pour les recherches et update.....
Et je suis pas un AS en sql je dirais.

n°1653888
anapajari
s/travail/glanding on hfr/gs;
Posté le 06-12-2007 à 15:27:31  profilanswer
 

commence à faire ton truc et reviens poser tes questions sqls quand tu bloques :)

n°1654021
hornetmen
GaZZzz... Et Flash....22
Posté le 06-12-2007 à 17:08:59  profilanswer
 

Voici le shéma de la base :

Code :
  1. CREATE TABLE `job_db_copy` (
  2.   `job_id` bigint(20) NOT NULL auto_increment,
  3.   `job_name_id` bigint(100) NOT NULL,
  4.   `job_start` datetime NOT NULL default '0000-00-00 00:00:00',
  5.   `job_end` datetime NOT NULL default '0000-00-00 00:00:00',
  6.   `job_duration` time NOT NULL default '00:00:00',
  7.   `job_status` varchar(15) NOT NULL,
  8.   `job_log` varchar(100) NOT NULL,
  9.   `server_id` bigint(20) NOT NULL default '0',
  10.   UNIQUE KEY `id` USING BTREE (`job_id`,`job_name_id`,`server_id`),
  11.   KEY `job_id` (`job_id`,`job_start`,`job_log`,`job_end`)
  12. ) ENGINE=MyISAM AUTO_INCREMENT=229727 DEFAULT CHARSET=utf8;
  13. CREATE TABLE `job_ref` (
  14.   `job_name_id` bigint(20) NOT NULL auto_increment,
  15.   `server_id` bigint(20) default NULL,
  16.   `job_name` varchar(100) default NULL,
  17.   `job_desc` varchar(200) default NULL,
  18.   `job_dep` varchar(300) default NULL,
  19.   UNIQUE KEY `id` (`job_name_id`,`server_id`,`job_name`),
  20.   KEY `job_name` (`job_name`,`job_desc`,`job_dep`(255))
  21. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  22. CREATE TABLE `srv_ref` (
  23.   `server_id` bigint(20) NOT NULL auto_increment,
  24.   `server_name` varbinary(20) NOT NULL,
  25.   PRIMARY KEY  (`server_id`,`server_name`)
  26. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Mon fichier a traiter ressemble à ca:
 
 

Code :
  1. ELCLP_BAT_34234_J_6I_1,2007-12-05  22:51:01,2007-12-05  22:51:15,00:00:14,COMPLETE,/replogs/log/ELCLP_BAT_34234_J_6I_1,SRVUS0001
  2. IVB6P_JOT_34234_J_RI_1,2007-12-01  07:50:11,2007-12-01  07:52:17,00:02:06,COMPLETE,/replogs/log/IVB6P_JOT_34234_J_RI_1,SRVUS0001
  3. ELCLP_ANT_34234_J_2E_1,2007-12-01  00:38:25,2007-12-01  00:38:39,00:00:14,COMPLETE,/replogs/log/ELCLP_ANT_34234_J_2E_1,SRVUS0001
  4. IVB6P_JWT_34234_J_JI_1,2007-12-01  08:13:49,2007-12-01  08:14:56,00:01:07,COMPLETE,/replogs/log/IVB6P_JWT_34234_J_JI_1,SRVUS0001
  5. IVEMP_JUT_34234_J_2E_1,2007-12-01  07:59:32,2007-12-01  08:02:35,00:03:03,COMPLETE,/replogs/log/IVEMP_JUT_34234_J_2E_1,SRVUS0001
  6. ELCLP_BBT_34234_J_2E_1,2007-12-05  22:51:26,2007-12-05  22:52:15,00:00:49,COMPLETE,/replogs/log/ELCLP_BBT_34234_J_2E_1,SRVUS0001
  7. IVB6P_JPT_34234_J_JI_1,2007-12-01  07:58:20,2007-12-01  07:59:25,00:01:05,COMPLETE,/replogs/log/IVB6P_JPT_34234_J_JI_1,SRVUS0001
  8. IVEMP_JOT_34234_J_PI_1,2007-12-01  07:21:48,2007-12-01  07:22:59,00:01:11,COMPLETE,/replogs/log/IVEMP_JOT_34234_J_PI_1,SRVUS0001
  9. IVE0P_BHI_34234_J_AI_1,2007-12-01  13:50:36,2007-12-01  13:51:56,00:01:20,COMPLETE,/replogs/log/IVE0P_BHI_34234_J_AI_1,SRVUS0001
  10. IVE0P_BJI_34234_J_4I_1,2007-12-05  23:18:31,2007-12-05  23:19:36,00:01:05,COMPLETE,/replogs/log/IVE0P_BJI_34234_J_4I_1,SRVUS0001
  11. IVB6P_JWT_34234_J_HI_1,2007-12-01  08:16:48,2007-12-01  08:18:01,00:01:13,COMPLETE,/replogs/log/IVB6P_JWT_34234_J_HI_1,SRVUS0001
  12. IVEMP_JPT_34234_J_HE_1,2007-12-01  07:52:24,2007-12-01  07:53:29,00:01:05,COMPLETE,/replogs/log/IVEMP_JPT_34234_J_HE_1,SRVUS0001
  13. IVEMP_JOT_34234_J_RI_1,2007-12-01  07:26:19,2007-12-01  07:27:35,00:01:16,COMPLETE,/replogs/log/IVEMP_JOT_34234_J_RI_1,SRVUS0001
  14. IVE0P_BBI_34234_J_CI_1,2007-12-05  23:24:14,2007-12-05  23:25:18,00:01:04,COMPLETE,/replogs/log/IVE0P_BBI_34234_J_CI_1,SRVUS0001
  15. ELCLP_AOT_34234_J_6I_1,2007-12-01  08:57:36,2007-12-01  08:57:58,00:00:22,COMPLETE,/replogs/log/ELCLP_AOT_34234_J_6I_1,SRVUS0001


 
 
A présent je lance un script php avec le nom du fichier a traiter en parametre qui fait ca:
 

Code :
  1. <?php
  2. include ("../inc/insert.inc" );
  3. //if(isset($_GET['file']))
  4. if(isset($argv[1]))
  5. {
  6. $file = $argv[1];
  7. $dest_dossier = 'd:\\exploit\\www\\myjobsearcher\\pages\\upload\\';
  8. $myfile = "$dest_dossier$file";
  9. $archdossier = 'd:\\exploit\\www\\myjobsearcher\\pages\\upload\\archives\\';
  10. $archfile = "$archdossier$file";
  11. $ligne = 1;
  12. $id_fichier = fopen ("$myfile","r" );
  13.    while ($tableau = fgetcsv($id_fichier, 1024, "," ))
  14.    {
  15.  $nb = count($tableau);
  16.  //echo "<h3>$nb champs dans la ligne $ligne: </h3>";
  17.  $ligne++;
  18.  $job_name=$tableau[0];
  19.  $job_start=$tableau[1];
  20.  $job_end=$tableau[2];
  21.  $job_duration=$tableau[3];
  22.  $job_status=$tableau[4];
  23.  $job_log=$tableau[5];
  24.  $server_name=$tableau[6];
  25.  //print ("$job_name $job_log" );
  26.  $server_name = strtoupper($server_name);
  27.      
  28.  // teste si le serveur existe
  29.  if ($ligne == "2" ) { print ("Insert is running (Please wait for \"Insert COMPLETE\" message before close this windows.<BR>" );}
  30.  $server_name_indb = exist_server($server_name);
  31.          
  32.          
  33.          
  34.  //print ("server_name_indb = $server_name_indb and server_name=$server_name<BR>" );
  35.  //Si le serveur existe pas, on le cree
  36.  if (is_null($server_name_indb))
  37.  {
  38.   //print ("Server $server_name don't exist in the database, we need to create it before !<BR>" );
  39.   create_server ($server_name);
  40.   //print ("Executing => $create_server_sql<BR><BR>" );
  41.  }
  42.  //on recupere l'id du serveur
  43.  $server_id = get_server_id($server_name);
  44.  //print ("Found : $server_id<BR>" );
  45.  //teste si le job est reference la table job_ref
  46.  $job_info = exist_job_name ($server_id,$job_name);
  47.  // si il existe pas, on le cree
  48.  if (is_null($job_info[0]))
  49.  {
  50.   //print ("Job $job_name pour le serveur $server_name non trouvé dans la ref<BR>" );
  51.   $job_name_create = create_job_name($job_name,$server_id);
  52.   ++$count_create_job;
  53.  }
  54.  else
  55.  {
  56.   //print ("Job $job_name pour le serveur $server_name trouvé dans la ref (job_id = $job_info[0])<BR>" );
  57.  }
  58.  //teste si le job a inserer existe dans la table job_db_copy, pour eviter les doublons
  59.  //$jobdb_id = get_jobdb_name_idold ($server_id,$job_name,$job_start,"$job_log",$job_status,$job_duration);
  60.  $jobdb_id = get_jobdb_name_id1 ($server_id,$job_name,$job_start);
  61.  //si il n'existe pas, on le cree
  62.  if (is_null($jobdb_id))
  63.  {
  64.   $job_name_id = get_job_name_with_job_id ($job_name,$server_id);
  65.   $insert_new_job = insert_new_job($server_id,$job_name_id,$job_start,$job_end,"$job_log",$job_status,$job_duration);
  66.   //print (" job $job_name est bon a inséerer<BR>" );
  67.   $insertme_status='OK';
  68.   ++$count_insert_job;
  69.  }
  70.  //si le job existe
  71.  else
  72.  {
  73.   //on teste si job_end,job_log,job_status,job_duration sont les même
  74.   //print ("<BR>Job $job_name on $server_name starting at $job_start in $job_status status is already present in the db. (New Function)<BR>" );
  75.   $job_log = ereg_replace("//","/",$job_log) ;
  76.   $jobdb_id = get_jobdb_name_id2 ($server_id,$job_name,$job_start,"$job_log",$job_status,$job_duration,$job_end);
  77.   //print ("$job_id<BR>" );
  78.   //si au moins un champs est different, on update la ligne avec les nouvelles donnees
  79.   if (is_null($jobdb_id))
  80.   {
  81.    $jobdb_id = get_jobdb_name_id1 ($server_id,$job_name,$job_start);
  82.    //print ("Line is different, need an update for this line => job_id $jobdb_id<BR>" );
  83.    $job_log = ereg_replace("//","/",$job_log) ;
  84.    $update_doublon = update_jobdb_doublon ($job_start,"$job_log",$job_status,$job_duration,$job_end,$jobdb_id,$job_status);
  85.    $insertme_status='OK';
  86.   ++$count_update_job;
  87.   }
  88.   //si c'est tous ces champs sont les memes, on passe
  89.   else
  90.   {
  91.    //print ("job_id find => $jobdb_id => nothing to do<BR>" );
  92.    ++$count_skipped_job;
  93.   }
  94.   //print ("Job $job_name on $server_name starting at $job_start in $job_status status is already present in the db. Zapingg :)<BR>" );
  95.  }
  96.            
  97.    }
  98.  
  99. //tous le jobs ont ete inserer, on rend la main
  100. if (isset($insertme_status))
  101. {
  102.  print ("Insert = $count_insert_job.<BR>" );
  103.  print ("Update = $count_update_job.<BR>" );
  104.  print ("Create = $count_create_job.<BR>" );
  105.  print ("Skip = $count_skipped_job.<BR>" );
  106.  print ("Insert is COMPLETE.<BR>" );
  107.  fclose ($id_fichier);
  108.  copy("upload/$file", "upload/archives/$file" );
  109.  unlink("upload/$file" );
  110. }
  111. }
  112. //si le fichier d'entree n'a pas ete trouve, on alerte
  113. else
  114. {
  115. print ("Don't find file : $file" );
  116. }
  117. ?>


 
 
 
Voila, aujourd"hui ce code fonctionne parfaitement.
Le problème c'est que c'est long car il fait ligne par ligne......Je suis à 10 requetes par secondes car il fait environ 2 lignes par secondes........(et 5 requetes par ligne).......
 
Sachant que le fichier à insérer contient généralement 20% d'update,10% d'insertion et 70% de doublons, je suis bloqué à ce niveau là.
 
 :jap:

n°1654043
anapajari
s/travail/glanding on hfr/gs;
Posté le 06-12-2007 à 17:51:09  profilanswer
 

oui et il est où le problème?
Ce qui est amusant c'est que tu es exactement dans ma 2eme remarque [:dawak]

n°1654044
hornetmen
GaZZzz... Et Flash....22
Posté le 06-12-2007 à 17:56:30  profilanswer
 

Le pb est que :
 
1 => il lit 1 ligne et requete 5 fois pour savoir ce qu'il doit faire (insert/update/nothing).
2 => il attends que la ligne 1 soit passé pour attaquer la ligne 2
 
Donc c'est chiant sur des milliers de lignes.
Je voudrait bien qu'il lise par exemple 300 lignes, execute en même temps les 300 requetes en même temps, et passe aux suivantes.
 
Le coup de loader dans une table temporaire, je veux bien, ce sera certainement le plus rapide......
Je sais avoir une table à l'image de mon CSV.
 
Je ne sais pas comment gérer mes insert/update/notthing apres en sql......

n°1654393
hornetmen
GaZZzz... Et Flash....22
Posté le 07-12-2007 à 11:44:42  profilanswer
 

Bon,
J'ai créé une table temporaire, et insérer mon fichier CSV brut dedans.
 
Le shéma:
 
CREATE TABLE `tmp2` (
  `job_name` varchar(100) NOT NULL,
  `job_start` datetime NOT NULL,
  `job_end` datetime NOT NULL,
  `job_duration` time NOT NULL,
  `job_status` varchar(15) NOT NULL,
  `job_log` varchar(500) NOT NULL,
  `server_name` varchar(45) NOT NULL,
  `job_id` bigint(20) NOT NULL auto_increment,
  PRIMARY KEY  (`job_id`),
  UNIQUE KEY `job_name` (`job_id`,`job_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 
Je suis un peu perdu avec le sql maintenant.


Message édité par hornetmen le 13-12-2007 à 14:50:18
mood
Publicité
Posté le 07-12-2007 à 11:44:42  profilanswer
 

n°1654519
leflos5
On est ou on est pas :)
Posté le 07-12-2007 à 14:32:44  profilanswer
 

Dans quel cas tu va choisir de faire un update ou rien :??:
 
Je suis presque sur que tout est faisable en quasiment une seule requête par ligne à coup de IGNORE et de ON DUPLICATE KEY UPDATE. Reste ma question à traiter :)

n°1654548
anapajari
s/travail/glanding on hfr/gs;
Posté le 07-12-2007 à 15:01:14  profilanswer
 

ce qui est sur c'est qu'il est dommage que mysql ne supporte pas "merge ... into" car il est sur que ça se faisait en 1 requête ;)
edit: et +1 sur la question précédente


Message édité par anapajari le 07-12-2007 à 15:01:27
n°1654557
hornetmen
GaZZzz... Et Flash....22
Posté le 07-12-2007 à 15:09:32  profilanswer
 

Ok, donc le cas ou je fais un update :
 
job_name_id/job_start sont pareil mais un des autre champs est différent => update de toutes les colones.
 
les inserts:
- si le server_name est pas présent dans srv_ref => update avant insertion pour avoir un server_name_id a renseigner dans job_db_copy
- si job_name n'est pas présent dans job_ref => update avant insertion pour avoir job_name_id a renseigner dans job_db_copy
 
:)

n°1654619
leflos5
On est ou on est pas :)
Posté le 07-12-2007 à 15:35:55  profilanswer
 

Je suis pas sur d'avoir compris, donc tu peux avoir qu'un couple (job_name_id,job_start) mais dont les valeurs peuvent changer :??:
=>Update systématique car mysql le passera à la trappe si pas besoin
 
Je comprends pas tes inserts où tu parles d'update alors que j'ai l'impression que tu veux faire une insertion avant?
=> trigger

n°1654635
hornetmen
GaZZzz... Et Flash....22
Posté le 07-12-2007 à 15:43:47  profilanswer
 

car dans la table job_db_copy, il y a server_id (ref vers table srv_ref) et job_name_id (ref ver job_ref) ;)

n°1654719
leflos5
On est ou on est pas :)
Posté le 07-12-2007 à 17:08:42  profilanswer
 

Donc tu inserts dans ces tables pour avoir les valeurs dans la table job_db_copy :??: Donc tu insères avant de faire l'update :??:

n°1654725
hornetmen
GaZZzz... Et Flash....22
Posté le 07-12-2007 à 17:21:48  profilanswer
 

PAr l'exemple : :)
 
J'ai un ligne
 
EXPDX84E,2007-01-30  23:50:30,2007-01-30  23:50:30,00:00:00,COMPLETE,/unicenter/log/EXE0PDX8.EXPDX84E.0001.20070130-235030,freo0092
 
Je teste si le nom de serveur est connu dans srv_ref :
Non => je cré le nom de serveur dans srv_ref et recupere son id pour l'ulitiser dans la table job_db_copy.
Donc oui, avant l'insert.
 
Je teste si le nom du job est connu dans job_ref :
Non => je cré le nom du job dans job_ref et recupere son id pour l'ulitiser dans la table job_db_copy.
Donc oui, avant l'insert.
 
 
 
Oui => je teste la présence du couple job_name et job_start dans la table job_db_copy
- Non Présent : je peux donc insérer ma ligne dans job_db_copy, car je suis sur que ce n'est pas un doublon ou un doublon a mettre a jour.
- Présent : update dans job_db_copy de ligne a mettre a jour.
 
Sachant que quand j'insere dans job_db_copy, je dois trouver un server_name_id et un job_name_id a la place des vrais valeurs (histoire que ce soit plus facile a administrer)
 
Voili, je sais pas si c'est clair....
 
En gros , pour chaque enregistrement server_name et job_name, ils doivent etre impérativement reférencés dans les tables job_ref et srv_ref (eh oui, comme ca j'ai un id ;))


Message édité par hornetmen le 07-12-2007 à 17:24:10
n°1654738
leflos5
On est ou on est pas :)
Posté le 07-12-2007 à 17:42:13  profilanswer
 

Donc utilises les triggers pour tes enregistrements dans les tables de références :)
 
Colle un index unique sur ce qui doit l'être, te pose pas de question et fait un insert on duplicate key update: si y'a rien à faire il le fera pas, si y'a duplication de la clé il update ce que tu veux :)
 
Fais une requête préparée avec un insert de masse et ça devrait passer bien plus rapidement :)

n°1654748
hornetmen
GaZZzz... Et Flash....22
Posté le 07-12-2007 à 17:47:09  profilanswer
 

Oui ca me semble bien plus simple comme ca.
Dans la pratique, je n'ai pas les connaissances pour le faire. .....  :jap:

n°1655213
leflos5
On est ou on est pas :)
Posté le 09-12-2007 à 12:41:56  profilanswer
 

Commence par les inserts, rejouter un index unique c'est rien, au pire utilise phpmyadmin y'a qu'à cliquer.
 
http://dev.mysql.com/doc/refman/5. [...] index.html
 
Pour le on duplicate key, suffit de faire ton insert normal et de rajouter "on duplicate key update col=valeur" tout simplement.
 
Pour le trigger, ça va être le plus dur mais au final rien de bien insurmontable :) L'avantage c'est que ta logique applicative est déportée sur le sgbd donc plus besoin de s'en occuper et l'intégrité est garantie.
 
http://dev.mysql.com/doc/refman/5. [...] ggers.html
http://maximilian.developpez.com/m [...] mysql5/#LB

n°1655242
yellu
Posté le 09-12-2007 à 13:39:08  profilanswer
 

A mon avis tu devrais utiliser des tableaux associatifs de PHP.
 
Tu fais 4 grosses select sur tes tables de references et tu stock tout dans des tableaux associatifs qui fond correspondre nom => cle.
 
Ensuite tu boucles sur ton fichier et tu fais
 

Code :
  1. foreach($lignes as $ligne) {
  2.   $info = $ligne[2];
  3.   $mon_serveur = $ligne[4];
  4.   if(!array_key_exists($mon_serveur, $serveurs)) {
  5.     mysql_query('INSERT INTO serveur .........', $conn);
  6.     $serveurs[$mon_serveur] = mysql_insert_id($conn); 
  7.   }
  8.   mysql_query('INSERT INTO lignes (info, serveur) VALUES (\''.$info.'\', '.$serveurs[$mon_serveur].');', $conn);
  9. }


 
De cette manière tu fais grossir tes tableaux de cle etrangere à la volée sans besoin de faire du SQL pour récupérer les cles.
 

n°1655569
leflos5
On est ou on est pas :)
Posté le 09-12-2007 à 23:58:58  profilanswer
 

Ou comment sortir la moissonneuse pour récupérer 2kg de blé...
Surtout que ça change rien au problème de base: vérifier et agir en conséquence ;)

n°1656023
yellu
Posté le 10-12-2007 à 16:43:28  profilanswer
 

leflos5 => Si ta réflexion s'adresse à ma proposition, je ne vois pas en quoi mon idée est plus couteuse dans la mesure ou il y aura une insert pour chaque ligne de chaque table et les consultations se feront via des tableaux phps donc accès mémoire et non fichiers.
 
Alors explique moi en quoi c'est contraignant ?

n°1656072
anapajari
s/travail/glanding on hfr/gs;
Posté le 10-12-2007 à 18:13:16  profilanswer
 

dans un cas tu laisses le sgbd (dont c'est le métier) s'en occuper.
Dans l'autre tu laisses le soin au developpeur de se débrouiller pour gérer correctement des tableaux monstrueux ( enfin qui peuvent l'être s'il y a beaucoup d'enregistrement à faire).
 
 

n°1656529
leflos5
On est ou on est pas :)
Posté le 11-12-2007 à 13:59:18  profilanswer
 

+1  
sans parler du coût en mémoire et en traitement :)
Alors que le sgbd lui mutualisera les ressources utilisées, pas le script :)
 
Si c'est une machine dédiée juste pour ça, juste pour quelques fois, je suis d'accord qu'on peut sortir le tractopelle pour un gravier, ça va plus vite que de chercher la balayette qu'on sait plus où elle peut se trouver et faire perdre 2h :D
Mais faut penser aussi au coût ne serait ce en temps pour les MAJ si doit y en avoir souvent ;)
 
 
L'avantage de déplacer la logique applicative sur la base c'est qu'après t'as plus besoin de te soucier de quoi que ça soit à ce niveau et donc plus de bug de donnée.

n°1656677
yellu
Posté le 11-12-2007 à 16:30:30  profilanswer
 

Vos concepts sont exacts mais s'adapte a des applications pas à des scripts de transitions ou de conversion.
 
En l'occurence entre générer des SELECT à la volée pour faire des tests de cohérence et la consultation d'un Array, j'opterai pour le Array, d'autant que tu n'as à modifier ta configuration serveur en utilisant ini_set et set_time_limit.

n°1656736
anapajari
s/travail/glanding on hfr/gs;
Posté le 11-12-2007 à 17:53:06  profilanswer
 

nan mais le truc que t'as pas compris c'est qu'on ne recommande pas non plus de génèrer  "DES" selects, mais qu''une seule requête gère l'insertion/mise a jour ( voir de deux si une seule est trop compliquée à écrire).
 
Et même pour des scripts de transitions ou de conversion, ce que tu recommandes n'est que rarement utilisable.
Il y a quelques semaines, on devait importer le fichier Insee des entreprise dans une base ( 220K lignes pour environ 250Mo) et bien je te garantis qu'en utilisant ta méthode le serveur aurait lentement succombé...
Et pourtant c'était bien un script de transition/conversion.  [:spamafote]

n°1656963
leflos5
On est ou on est pas :)
Posté le 12-12-2007 à 02:28:03  profilanswer
 

D'où ma réponse: si c'est pour faire une moulinette foireuse pour une fois ça sera plus rapide à mettre en oeuvre de faire un truc foireux (maintenant un bug au milieu et zou la cohérence d'où l'importance d'avoir une base qui gère le plus possible la cohérence) pour une fois je suis d'accord.
 
Mais comme le dis anapajari, ça dépend aussi du volume, des performances du système, du temps qu'on a à accorder à la MAJ, de l'impact résonnable que l'on peut s'autoriser...
 
 
Bref si c'est pas pour une fois pour quelques milliers de tuples on vire vite au drame en encourageant qui que ça soit à aller dans le sens du script vilain pour "dépanner" qui mettra à genoux les machines avec leurs utilisateurs :)
 
Enfin on sait pas vraiment le contexte et les contraintes de temps/disponibilité donc :spamafote:

n°1657059
yellu
Posté le 12-12-2007 à 11:20:02  profilanswer
 

Il a un fichier de 4Mo et les array qui sont créée à la volés sont la pr gérer l'unicité des clef étrangères donc à priori ne devrait pas grossir des masses :s  
Le contexte m'as semblé permettre l'utilisation de cette moulinette qui n'est pas "foireuse".
J'admet qu'elle fait le boulot qui ne lui est théoriquement pas donné à faire mais elle ne le fera pas mal.
 
Maintenant ce que j'ai pris en compte cette personne à l'air peu familière avec le SQL et j'essaiyai donc de lui expliquer une autre vision du problème.
 
Pour le SQL sinon l'aspect de faire de l'INSERT IGNORE sur un champ UNIQUE est peut être un procédé un peu compliqué, je te conseillerai dans un premier temps de bien apréhender la différence entre INSERT et REPLACE que mysql propose.
 

n°1657062
omega2
Posté le 12-12-2007 à 11:23:56  profilanswer
 

Attention avec REPLACE. Ca revient à faire un delete (basé sur la clé primaire de la table) suivit d'un insert. Si t'as d'autres tables qui utilisent les id de celle ci alors il ne faut surtout pas faire de REPLACE sous peine de ne plus avoir la moindre cohérence entre ta table et les autres.

n°1657064
yellu
Posté le 12-12-2007 à 11:26:19  profilanswer
 

C'est pas de l'autoincrement ici

n°1657078
omega2
Posté le 12-12-2007 à 11:47:10  profilanswer
 

yellu > Regarde mieux les structures des tables qu'il utilise, moi je vois bien un autoincrément dans job_db_copy, job_ref et srv_ref. Ta remarque est donc fausse. Par contre, vu la structure de sa base, mon intervention est hors sujet vu qu'il ne peut pas faire de replace vu que sa clé primaire contient entre autre la colonne "auto-incrémenté". S'il voulait faire un replace dans ces conditions, alors il faudrait d'abord qu'il cherche les id de la colonne auto-incrémenté et dans ce cas autant faire ensuite un replace classique.
 
PS : Quelqu'un voit un intérêt à la création d'une clé primaire qui contient à la fois une colonne autoincrément et d'autres colonnes?


Message édité par omega2 le 12-12-2007 à 11:48:39
n°1657129
yellu
Posté le 12-12-2007 à 13:45:35  profilanswer
 

Je parle des référent pas de la table principal dans laquelle il n'y aura que des insertions.
 
Il inserre des objets dans une table cette objet a une clef etrangere, il se demande si il doit créer une ligne pour cette objet etranger ou non, il peut faire un REPLACE dans la table de cet objet étrangère en forçant le primary key avec la valeur qu'il avais dans la table principale.

n°1657574
hornetmen
GaZZzz... Et Flash....22
Posté le 13-12-2007 à 10:30:45  profilanswer
 

Bonjour :)
 
Je vois qu'il y a matiere.
Le contexte est le suivant :
 
J'ai un serveur disponible et qui ne sert uniquement à heberger la base Mysql et la partie Apache/PHP.
Je peux etre gourmant donc, pas de haute dispo rien du tout.
 
Je tente actuellement d'ecrire les requetes qui me permettent de faire les INSERT/UPDATE à partir des données injectées dans la table temporaire mais j'en suis encore......dans le néant :)
 

n°1658028
leflos5
On est ou on est pas :)
Posté le 13-12-2007 à 22:42:12  profilanswer
 

En ce qui me concerne, je maintiens ma proposition pour une seule chose: faire propre et aussi aller là où on maitrise pas pour tester et savoir faire après!
 
Si ça presse fais le vilain tableau... Ou ta méthode requête par requête pour chaque ligne :spamafote:
 
Toutes les solutions marcheront, la plus intéressante intellectuellement étant de se servir du sgbd et ses contraintes d'intégrité + trigger (et pourquoi pas une procédure stockée :D ), ce qui est son boulot, pas besoin de réinventer la roue carrée ( :whistle: )

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  PHP

  Aide pour optimiser mon code => insert bdd

 

Sujets relatifs
erreur code[Résolu] [WSQL] Besoin d'aide - Procedure
besoin aide pour requêteaide pour site creation de site
erreur code jeu de nombreBesoin d'aide double clique
[java ]générateur de pseudo codeCode formulaire non-interprété [Résolu] & mémorisation valeurs
Aide POO 
Plus de sujets relatifs à : Aide pour optimiser mon code => insert bdd


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR