non j'ai pris le tps. la requete fait ds les 4s.
tt est mis en memoire via fetchall_arrayref.
ok, j'ai enleve les hash car la 2e boucle for sortait des la 1ere iteration
dc le gain n'etait pas significatif.
voici la methode complete.....
sub traficApplicatifEmissionReception {
my ($this)=shift;
my ($debut,$fin,$precision,$requete_appli,$requete_avg,$title)=@_;
my $writer=new LogSecureWriter;
my $path;
#print "debut : $debut<BR>";
#print "fin : $fin<BR>";
#print "precision : $precision<BR>";
#print "requete_appli : $requete_appli<BR>";
#print "requete_avg : $requete_avg<BR>";
#print "title : $title<BR>";
#Exemple de date a fournir en parametre a la Methode
#$debut = DateTime->new( year => 2004,
# month => 5,
# day => 14,
# hour => 00,
# minute => 00,
# second => 47,
# );
##############################
#Configuration du graph #
# --> Parametres modifiables #
##############################
#Resolution du graph en pixels
my $graph = GD::Graph::area->new(1024,768); # resolution : 1024*768 Pixels
#Interval des Affichage des dates en X
#Sur un graph en 1024*768 on peu avoir 40 labels en X maximum , apres sa devien illisible
my $interval_xLabel=20; #20 est une bonne valeur
#on fera une requete tout les interval_requete interval
my $intervalle_calcul = $precision;
#####################
#Calcul de l'echelle#
#####################
my $duree_second=$fin->subtract_datetime_absolute($debut); #Retourne uniquement des secondes
#DEBUG: print"<BR>----DEBUT : ".Dumper($debut)."<BR>";
#DEBUG: print"<BR>----FIN : ".Dumper($fin)."<BR>";
#DEBUG: print"<BR>----duree : ".Dumper($duree_second)."<BR>";
my $interval= DateTime::Duration->new( years => 0,
months => 0,
weeks => 0,
days => 0,
hours => 0,
minutes => 0,
seconds => $intervalle_calcul,
nanoseconds => 0 );
#my $moitier_interval= DateTime::Duration->new( years => 0,
# months => 0,
# weeks => 0,
# days => 0,
# hours => 0,
# minutes => 0,
# seconds => ($intervalle_calcul/2),
# nanoseconds => 0 );
#####################################################
#Recuperation des 10 Applications les plus utilisées#
#####################################################
my @applications;
my %autres;
my %tabAutres;
my @finalAutres;
my %hashData;
my %application_hash;
my %first_hash;
my %second_hash;
my %third_hash;
my %fourthly_hash;
my %fifthly_hash;
my $bddinjector=new BddInjector;
if(!(my $dbh=$bddinjector->BddConnect)){ #Connection a la base
$writer->secureAppend("BDD_ERROR.LOG","la méthode traficApplicatifEmissionReception() de l'objet".__PACKAGE__." a échoué: impossible de se connecter à la base de données :$DBI::errstr.\n" );
return 0;
}else{
# /!\ Utilisation de la requete passé en parametre /!\
my $sth_appli=$dbh->prepare($requete_appli);
#print "REQ :<BR>$requete_appli<BR>";
if(!($sth_appli->execute())){
#echec de l'execution de la requête
$writer->secureAppend("BDD_ERROR.LOG","dans la méthode traficApplicatifEmissionReception() de l'objet".__PACKAGE__.": échec de la requête : $requete_appli.$DBI::errstr.\n" );
return 0;
}else{
#cdd+
$secondesAP = $this->GetTimeSecondes();
$DeltaT = $secondesAP - $secondesAV;
print "<FONT SIZE=3 COLOR=\"red\">requete_appli $DeltaT sec<BR></FONT>";
#cdd-
$secondesAV = $this->GetTimeSecondes();#cdd
#Cette méthode est utilisée pour faire en sorte que toutes les
#données (lignes) soient retournées par la requête SQL.
#Elle retourne une référence à un tableau de références à des
#tableaux pour chaque ligne.
my $table = $sth_appli->fetchall_arrayref or die "$sth_appli->errstr\n";
#cdd+
$secondesAP = $this->GetTimeSecondes();
$DeltaT = $secondesAP - $secondesAV;
print "<FONT SIZE=3 COLOR=\"red\">fetchall_arrayref1 $DeltaT sec<BR></FONT>";
#cdd-
$secondesAV = $this->GetTimeSecondes();#cdd
my $i_= 0;
my $i = 0;
my $j;
#for $i ( 0 .. $#{$table} )
foreach my $row (@$table)
{
#print Dumper(@$row[0])."-".Dumper(@$row[1])."-".Dumper(@$row[2])."-".Dumper(@$row[3])."<BR>";
if (@$row[3] >= 1)
{
#Limite minimum 1%
if ((@$row[0] eq '') and (@$row[1] eq ''))
{
#print "Application NON REFERENCEE<BR>";
#$first_hash{''} = $i;
#$second_hash{''} = $i;
#$third_hash{@$row[2]} = $i;
my @tab=('','',@$row[2],{},{},[]); #On stock donc le port_destination
push(@applications,\@tab);
}
else
{
#print "Application REFERENCEE<BR>";
#cdd Le {} alloue un hachage anonyme ne contenant aucune paire clé/valeur, et le retourne.
#[] et {} st des constructeurs anonymes
#$first_hash{@$row[0]} = $i;
#$second_hash{@$row[1]} = $i;
#$third_hash{''} = $i;
my @tab=(@$row[0],@$row[1],'',{},{},[]);
push(@applications,\@tab);
}
}
#$third_hash{@$row[2]} = $i;
$i++;
}
#cdd+
$secondesAP = $this->GetTimeSecondes();
$DeltaT = $secondesAP - $secondesAV;
print "<FONT SIZE=3 COLOR=\"red\">traitement fetchrow_arrayref 1 en $DeltaT sec<BR></FONT>";
#cdd-
}
#print"APPLICATIONS : ".Dumper(@applications)."<BR>";
$sth_appli->finish;
###################################
#Construction du tableau de donnée#
###################################
my @xLabels; #Tableau des labels
my $maxValue=1; #Valeur Maximum de l'axe Y
my $j=0; #Compteur pour l'affichage des Labels en X
my $z=0;
#my $i=0;
$secondesAV = $this->GetTimeSecondes();#cdd
my $requete = $requete_avg;
#print "<BR><BR>DATA : $requete<BR><BR>";
my $sth_avg=$dbh->prepare($requete);
if(!($sth_avg->execute())){
#echec de l'execution de la requête
$writer->secureAppend("BDD_ERROR.LOG","dans la méthode traficApplicatifEmissionReception() de l'objet".__PACKAGE__.": échec de la requête : $requete.$DBI::errstr.\n" );
return 0;
}
#cdd+
$secondesAP = $this->GetTimeSecondes();
$DeltaT = $secondesAP - $secondesAV;
print "<FONT SIZE=3 COLOR=\"red\">requete_avg $DeltaT sec<BR></FONT>";
#cdd-
######################################
$secondesAV = $this->GetTimeSecondes();#cdd
my $table = $sth_avg->fetchall_arrayref or die "$sth_appli->errstr\n";
#cdd+
$secondesAP = $this->GetTimeSecondes();
$DeltaT = $secondesAP - $secondesAV;
print "<FONT SIZE=3 COLOR=\"red\">fetchall_arrayref2 $DeltaT sec<BR></FONT>";
#cdd-
$secondesAV = $this->GetTimeSecondes();#cdd
my($i, $j);
#for $i ( 0 .. $#{$table} )
foreach my $row (@$table)
{
#print" ".Dumper($table->[$i])."<BR>";
#Ligne : $VAR1 = [ '2176', '0', '2005-11-25 06:47:20.491787', '1', '0', '3478' ];
#print "row[0-1-2-3-4-5] : @$row[0]-@$row[1]-@$row[2]-@$row[3]-@$row[4]-@$row[5]<BR>";
$my_i++;
$secondesAV1 = $this->GetTimeSecondes();#cdd
############################
#Determination de l'interval
my $volume = @$row[0];#$table->[$my_k]->[0];
my $duree = @$row[1];#$table->[$my_k]->[1];
#$table->[$my_k]->[2] =~ /^(\d*)-(\d*)-(\d*)\s(\d*)
\d*)
\d*)\.?.*$/i ; #Date_debut
@$row[2] =~ /^(\d*)-(\d*)-(\d*)\s(\d*)
\d*)
\d*)\.?.*$/i ; #Date_debut
my $A= DateTime->new(year => $1,
month => $2,
day => $3,
hour => $4,
minute=> $5,
second=> $6,
);
my $interval_flux_seconde= $A->subtract_datetime_absolute($debut);
my $interval_flux= $interval_flux_seconde->seconds;
#DEBUG:print "--Interval Flux : $interval_flux <BR>";
###########################
#Saut en cas de dépassement
if ($interval_flux>($duree_second->seconds)) {
next;
}
###############################
#Determination de l'application
my $id = 0;
my $ref_data;
my %tmpData;
my $ident = "autre";
#print ("table->[$i]->[3] : @$row[3]<BR>" );
#print ("table->[$i]->[4] : @$row[4]<BR>" );
#print ("table->[$i]->[5] : @$row[5]<BR><BR>" );
#for (my $i = 0; $i <= $#tab; $i++) {$r += $tab[$i];}
#foreach my $elm (@tab) {$r += $elm;}
foreach my $elm (@applications)
#for (my $k=0; $k<@applications; $k++)
{
#Correction 5/11/04 : plus de test sur "ligne[x] ne 0" --> non prise en compte des donnée quand port_appli==0
if (( (@$row[3] ne '') && (@$row[3] eq $elm[0]) ) ||
( (@$row[4] ne '') && (@$row[4] eq $elm[1]) ) ||
( (@$row[5] ne '') && (@$row[5] eq $elm[2]) ))
{
#Ce flux appartient bien a cette application
#On ajoute donc les données de ce flux
$ref_data=$applications[$k]->[3];
%tmpData=%{$ref_data};
$ident=$k;
#Ajout 8/11/04 : evite de continuer a chercher l'application quand elle a ete trouvée
last;
}
}
##################################
#Ajout des donnés suivant la duree
#print "interval_flux($interval_flux) Volume($volume) ident($ident)<BR>";
if ($duree == 0)
{
#La durée du flux est nulle
if ($ident eq "autre" )
{
$autres{$interval_flux}+=$volume;
}
else
{
$tmpData{$interval_flux}+=$volume;
$applications[$ident]->[3]=\%tmpData;
}
}
else
{
#for (my $i = 0; $i <= $#tab; $i++) {$r += $tab[$i];}
#foreach my $elm (@tab) {$r += $elm;}
#print "duree : $duree";
foreach $i (0 .. $duree)
#for(my $i=0;$i<$duree;$i++)
{
if (not( (($interval_flux+$i)>($duree_second->seconds)) ) )
{
#Si pas de depassement
if ($ident eq "autre" )
{
$autres{$interval_flux+$i}+=$volume/$duree;
}
else
{
$tmpData{$interval_flux+$i}+=$volume/$duree;
$applications[$ident]->[3]=\%tmpData;
}
}
}
}
#print" ".Dumper($applications[$ident]->[0]);
#print" ".Dumper($applications[$ident]->[1]);
#print" ".Dumper($applications[$ident]->[2]);
#print" ".Dumper($applications[$ident]->[3]);
#print" ".Dumper($applications[$ident]->[4])."<BR><BR><BR>";
$my_k++;
}
#cdd+
$secondesAP = $this->GetTimeSecondes();
$DeltaT = $secondesAP - $secondesAV;
print "<FONT SIZE=3 COLOR=\"red\">traitement fetchrow_arrayref2[$my_i] en $DeltaT sec<BR></FONT>";
$my_i = 0;
#cdd-
$sth_avg->finish;
$secondesAV = $this->GetTimeSecondes();#cdd
##########################################################
#Creation des tableaux de donnée pour l'interval de calcul
#for (my $k=0; $k<@applications; $k++){$applications[$k]->[0]} #$elm[0] = $applications[$k]->[0]
foreach my $elm (@applications){ #Pour chaque application
#for (my $k=0; $k<@applications; $k++){ #Pour chaque application
my $ref_dataSet = $elm[3];
my %dataSet = %{$ref_dataSet};
my $ref_tab = $elm[4];
my %tab = %{$ref_tab};
for(my $i=0;$i<($duree_second->seconds);$i=$i+$intervalle_calcul) {
for(my $j=$i;$j<$i+$intervalle_calcul;$j++) {
if (defined($dataSet{$j})) {
$tab{$i}+=(($dataSet{$j})/($intervalle_calcul));
}else{
$tab{$i}+=0;
}
}
}
$elm[4] = \%tab;
}
for(my $i=0;$i<($duree_second->seconds);$i=$i+$intervalle_calcul) {
for(my $j=$i;$j<$i+$intervalle_calcul;$j++) {
if (defined($autres{$j})) {
$tabAutres{$i}+=(($autres{$j})/($intervalle_calcul));
}else{
$tabAutres{$i}+=0;
}
}
}
#on balance dans le jeu de données
foreach my $elm (@applications) {#Pour chaque application
#for (my $k=0; $k<@applications; $k++){$applications[$k]->[0]} #$elm[0] = $applications[$k]->[0]
#for (my $k=0; $k<@applications; $k++){ #Pour chaque application
my $ref_dataSet = $elm[4];
my %dataSet = %{$ref_dataSet};
my $ref_finalSet = $elm[5];
my @finalSet = @{$ref_finalSet};
for(my $i=0;$i<($duree_second->seconds);$i=$i+$intervalle_calcul) {
push(@finalSet,$dataSet{$i});
}
$elm[5] = \@finalSet;
}
for(my $i=0;$i<($duree_second->seconds);$i=$i+$intervalle_calcul) {
push(@finalAutres,$tabAutres{$i});
}
##########################
#Construction de l'echelle
my $cpt=0;
#foreach $i (0 .. (($duree_second->seconds)/$intervalle_calcul)){
for(my $i=0;$i<(($duree_second->seconds)/$intervalle_calcul);$i++) {
if ($cpt == $interval_xLabel ) {
$cpt=0;
my $tempLabel = $debut+ ($i*$interval);
$xLabels[$i]=$tempLabel->strftime("%H:%M:%S" );
}else{
$xLabels[$i]='';
}
$cpt++;
}
################################################################################
#Remplacement du Numero d'appli par le nom et construction du tableau de donnée#
################################################################################
my @data; #Les donnée a tracer
my @legende; #Les legendes du graph
#Tableau contenant les donnée a tracer sur le graph
push (@data,\@xLabels);
#Construction du tableau Data qui contiendra les donnée du graph a partir du tableau Application
foreach my $elm (@applications) {
#for(my $i=0;$i<(@applications);$i++) {
my $requete_nom;
my $unknow=0;
if (($elm[0]==0) and ($elm[1]==0)) { #Affichera le numero de port destination
push(@legende,"[inconnue] port : $elm[2]" );
$unknow=1;
}elsif ($elm[0]==0){ #Affichera le nom d'appli speciale
$requete_nom = " SELECT application_spe.nom,application_spe.port FROM application_spe";
$requete_nom .= " WHERE application_spe.fk_analyses_id=$this->{INDEX_ANALYSE} ";
$requete_nom .= " AND application_spe.id=$elm[1] ";
}else{ #Affichera le nom d'appli par default
$requete_nom = " SELECT application.nom,application.port FROM application ";
$requete_nom .= " WHERE application.id=$elm[0] ";
}
if ($unknow!=1) {
my $sth_nom=$dbh->prepare($requete_nom);
if(!($sth_nom->execute())){
#echec de l'execution de la requête
$writer->secureAppend("BDD_ERROR.LOG","dans la méthode traficApplicatifEmissionReception() de l'objet".__PACKAGE__.": échec de la requête : $requete_nom.$DBI::errstr.\n" );
return 0;
}else{
while(my $ligne=$sth_nom->fetchrow_arrayref){
#while(my @ligne=$sth_nom->fetchrow_array){
push(@legende,"$ligne->[0] ($ligne->[1])" );
}
}
$sth_nom->finish;
}
push (@data,$elm[5]); #Donnée pour chaque application
my @verif=@{$elm[5]};
#print "<BR><BR>***Nb Elem : $#verif***<BR><BR>";
}
#On met les applications autres ( id = 0 )
push (@data,\@finalAutres);
push(@legende,'Autres');
$dbh->disconnect;
###########################
#Construction du Graphique#
###########################
#DEBUG: print"FINAL DATA : ".Dumper(@data)."<BR><BR>";
#DEBUG: print"LEGENDE DATA : ".Dumper(@legende)."<BR><BR>";
#Preparation de l'object Graph
$graph->set(
x_label => "Horaires",
y_label => ' Bit / seconde',
title => "$title",
x_label_skip => 1,
x_labels_vertical => 1,
legend_placement =>'BL',
long_ticks => 0,
x_ticks =>0,
cumulate =>1,
fgclr =>'black',
accentclr =>'black',
labelclr =>'black',
valuesclr =>'black',
axislabelclr =>'black',
boxclr => 'white',
dclrs =>['marine','orange','pink','cyan','yellow','lblue','lgray','purple','lgreen','red','lbrown'],
l_margin =>10,
r_margin =>10,
y_min_value =>0,
# y_max_value =>int($maxValue),
) or warn $graph->error;
#Couleur predefinies :
#white, lgray, gray, dgray, black, lblue, blue, dblue, gold,
#lyellow, yellow, dyellow, lgreen, green, dgreen, lred, red,
#dred, lpurple, purple, dpurple, lorange, orange, pink, dpink,
#marine, cyan, lbrown, dbrown.
$graph->set_legend(@legende);
$graph->set_legend_font(GD::Font->MediumBold);
$graph->set_title_font(GD::Font->MediumBold);
$graph->set_x_axis_font(GD::Font->MediumBold);
$graph->set_y_axis_font(GD::Font->MediumBold);
$graph->set_x_label_font(GD::Font->MediumBold);
$graph->set_y_label_font(GD::Font->MediumBold);
#Tracage du graph
#Enregistrement du graph dans un fichier
my $file=$title;
$file=~ s/(\s)/_/g; #On remplace les escape dans le $title par des _
my $path="/$this->{IMG_PATH}/$file.png";
open(IMG, ">$path" );
binmode IMG;
print IMG $graph->plot(\@data)->png or die $graph->error;
close IMG;
#Convertion du Png en Jpg
my $filename=$this->png2jpg($path);
$writer->secureAppend("GRAPHS.LOG"," --> Creation de $filename \n" );
#cdd+
$secondesAP = $this->GetTimeSecondes();
$DeltaT = $secondesAP - $secondesAV;
print "<FONT SIZE=3 COLOR=\"red\">reste du traitement en $DeltaT sec<BR></FONT>";
#cdd-
return $filename;
}
}
en entree j'ai ca :
$VAR1 = '1'; -$VAR1 = '0'; -$VAR1 = '4662'; -$VAR1 = '57';
$VAR1 = '1'; -$VAR1 = '0'; -$VAR1 = '4660'; -$VAR1 = '4';
$VAR1 = '1'; -$VAR1 = '0'; -$VAR1 = '7039'; -$VAR1 = '3';
$VAR1 = '1'; -$VAR1 = '0'; -$VAR1 = '12896'; -$VAR1 = '2';
$VAR1 = '1'; -$VAR1 = '0'; -$VAR1 = '4024'; -$VAR1 = '2';
$VAR1 = '1'; -$VAR1 = '0'; -$VAR1 = '4221'; -$VAR1 = '2';
$VAR1 = '1'; -$VAR1 = '0'; -$VAR1 = '7561'; -$VAR1 = '2';
$VAR1 = '1'; -$VAR1 = '0'; -$VAR1 = '4118'; -$VAR1 = '2';
$VAR1 = '1'; -$VAR1 = '0'; -$VAR1 = '3938'; -$VAR1 = '1';
$VAR1 = '1'; -$VAR1 = '0'; -$VAR1 = '7812'; -$VAR1 = '1';
traitement fetchrow_arrayref 1 en 0 sec
APPLICATIONS1 :
$VAR1 = [ '1', '0', '', {}, {}, [] ];
$VAR2 = [ '1', '0', '', {}, {}, [] ];
$VAR3 = [ '1', '0', '', {}, {}, [] ];
$VAR4 = [ '1', '0', '', {}, {}, [] ];
$VAR5 = [ '1', '0', '', {}, {}, [] ];
$VAR6 = [ '1', '0', '', {}, {}, [] ];
$VAR7 = [ '1', '0', '', {}, {}, [] ];
$VAR8 = [ '1', '0', '', {}, {}, [] ];
$VAR9 = [ '1', '0', '', {}, {}, [] ];
$VAR10 = [ '1', '0', '', {}, {}, [] ];
requete_avg 4 sec
fetchall_arrayref2 0 sec
row[0-1-2-3-4-5] : 3904-0-2005-11-25 06:54:06.662454-708-0-500
row[0-1-2-3-4-5] : 0-0-2005-11-24 19:17:00.185121-1-0-4672
row[0-1-2-3-4-5] : 2176-0-2005-11-25 06:44:13.653105-1-0-3478
row[0-1-2-3-4-5] : 5504-0-2005-11-24 17:09:41.142196-119-0-80
300 000 lignes comme ca.
merci de ton aide, c sympa