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

Limite les requetes SQL en mettant dans un tableau ?

5 réponses
Avatar
Mag
Bonjour,

je suis en train de revoir un ancien script perl
que j'avais fait (attention je suis debutante).

Ce script interroge une base MySQL mais je le trouve
tres lents du avant tous a de multiple requete identique.

J'aimerais donc savoir si il est possible de faire une requete
unique sur une table qui va recuperer tous les enregistrements
(20 ene d'enregistrement a 4 champs) de celle ci, les mettres dans
un tableau memoire et qu'ensuite je puisse l'interroger "en memoire"

Comment je peux faire cela ?

Merci d'avance

5 réponses

Avatar
Paul Gaborit
À (at) Wed, 10 Jan 2007 07:55:10 +0100,
Mag écrivait (wrote):
je suis en train de revoir un ancien script perl
que j'avais fait (attention je suis debutante).

Ce script interroge une base MySQL mais je le trouve
tres lents du avant tous a de multiple requete identique.

J'aimerais donc savoir si il est possible de faire une requete
unique sur une table qui va recuperer tous les enregistrements
(20 ene d'enregistrement a 4 champs) de celle ci, les mettres dans
un tableau memoire et qu'ensuite je puisse l'interroger "en memoire"

Comment je peux faire cela ?


C'est le fonctionnement basique d'une requête 'select' de SQL. En
Perl, pour faire cela, on passe par DBI (et DBD::mysql si on utilise
MySQL). Pour récupérer tous les résultats d'un 'select', on peut
utiliser l'une des méthodes 'selectall_arrayref' ou
'selectall_hashref'...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
espie
In article <45a48dd2$0$308$,
Mag wrote:
Bonjour,

je suis en train de revoir un ancien script perl
que j'avais fait (attention je suis debutante).

Ce script interroge une base MySQL mais je le trouve
tres lents du avant tous a de multiple requete identique.

J'aimerais donc savoir si il est possible de faire une requete
unique sur une table qui va recuperer tous les enregistrements
(20 ene d'enregistrement a 4 champs) de celle ci, les mettres dans
un tableau memoire et qu'ensuite je puisse l'interroger "en memoire"


Il est possible de faire plein de choses. A la limite, montrez-nous
le bout qui va bien de votre script, on vous dira comment l'accelerer...

Avatar
Mag

Il est possible de faire plein de choses. A la limite, montrez-nous
le bout qui va bien de votre script, on vous dira comment l'accelerer...


;=)

pour faire simple:

sub get_data_cdr {
$dbh = DBI->connect($connection_src,$userid_src,$passwd_src);
$query = "SELECT
calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,duration,billsec,disposition
FROM $tb_source_ipbx";
$sth = $dbh->prepare($query);
$sth->execute();
while (my @ref = $sth->fetchrow_array()) {

## On mets en variable les champs de la base
$date_de_l_appel = @ref[0];
$clid = @ref[1];
$src = @ref[2];
$dst = @ref[3];
$dcontext = @ref[4];
$channel = @ref[5];
$dstchannel = @ref[6];
$lastapp = @ref[7];
$lastdata = @ref[8];
$duration = @ref[9];
$billsec = @ref[10];
$disposition = @ref[11];
##

## Execution des Traitements sur la ligne de données
&analyse_context;
}
}

Donc j'ai une base de données A que j'interroge ... pour chaque ligne je
lance l'analyse:

sub analyse_context {
$dbh_analyse_context =
DBI->connect($connection_dst,$userid_dst,$passwd_dst);
$query_analyse_context = "SELECT context,id_client,private,ipbx
FROM $tbl_script_context WHERE context='$dcontext'";
$sth_analyse_context =
$dbh_analyse_context->prepare($query_analyse_context);
$sth_analyse_context->execute();
@analyse_context=$sth_analyse_context->fetchrow_array();
$id_client=@analyse_context[1];
if (@analyse_context[0] eq $dcontext) {
if (@analyse_context[2] eq "0") {
if (@analyse_context[3] eq "0") {
&traitement_num_appele_ipbx;
}
&calcul_tarification;
&insertion_logs_details;
}
else {
if (@analyse_context[3] eq "0") {
&traitement_num_appele_ipbx;
}
&relation_private_clid;
&calcul_tarification;
&insertion_logs_details;
}
}
}

en resume, pour chaque ligne de la base A, je fais une requete sur la
Base B pour savoir l'id du client qui a genere la ligne sur la base A.

Ce que je trouve dommage dans mon script, c'est que la base B ne
contient que 20 clients ... alors si je pouvais en une seul requete
charger en memoire tous les client et apres interroge cette memoire sans
passer par une requete sql, je pense que cela serait plus rapide ;=)



a+
mag

Avatar
espie
In article <45a4b009$0$322$,
Mag wrote:

Il est possible de faire plein de choses. A la limite, montrez-nous
le bout qui va bien de votre script, on vous dira comment l'accelerer...


;=)

pour faire simple:

sub get_data_cdr {
$dbh = DBI->connect($connection_src,$userid_src,$passwd_src);
$query = "SELECT
calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,duration,billsec,disposition
FROM $tb_source_ipbx";


Je suis un peu inquiet quant au $tb_source_ibpx, surtout quand je vois la suite...


$sth = $dbh->prepare($query);
$sth->execute();
while (my @ref = $sth->fetchrow_array()) {

## On mets en variable les champs de la base
$date_de_l_appel = @ref[0];
Bon, deja, ca c'est faux...


@ref[0], c'est pas l'element 0 de ref, c'est un slice a un element.
$ref[0], c'est mieux.
Dans ce cas de figure, il vaut mieux utiliser bind_params de toutes facons,
puisque vous etes en train de faire son boulot.

$clid = @ref[1];
$src = @ref[2];
$dst = @ref[3];
$dcontext = @ref[4];
$channel = @ref[5];
$dstchannel = @ref[6];
$lastapp = @ref[7];
$lastdata = @ref[8];
$duration = @ref[9];
$billsec = @ref[10];
$disposition = @ref[11];
##

## Execution des Traitements sur la ligne de données
&analyse_context;
}
}

Donc j'ai une base de données A que j'interroge ... pour chaque ligne je
lance l'analyse:

sub analyse_context {
$dbh_analyse_context =
DBI->connect($connection_dst,$userid_dst,$passwd_dst);


Deja, remonter cette connexion au dessus et la passer en parametre a la
fonction. C'est idiot de fermer/ouvrir la meme base tout le temps.

$query_analyse_context = "SELECT context,id_client,private,ipbx
FROM $tbl_script_context WHERE context='$dcontext'";
$sth_analyse_context =
$dbh_analyse_context->prepare($query_analyse_context);
$sth_analyse_context->execute();


Remonter la requete aussi.
En fait, dcontext n'a rien a y faire... il faut apprendre a utiliser
les placeholder.

Ces trois lignes se reecrivent en:
$query_analyse_context = "SELECT context,id_client,private,ipbx
FROM $tbl_script_context WHERE context=(?)";
$sth_analyse_context =
$dbh_analyse_context->prepare($query_analyse_context);
$sth_analyse_context->execute($dcontext);


@analyse_context=$sth_analyse_context->fetchrow_array();
$id_client=@analyse_context[1];
if (@analyse_context[0] eq $dcontext) {
??? probleme de requete, je presume.

if (@analyse_context[2] eq "0") {
if (@analyse_context[3] eq "0") {
&traitement_num_appele_ipbx;
}
&calcul_tarification;
&insertion_logs_details;
}
else {
if (@analyse_context[3] eq "0") {
&traitement_num_appele_ipbx;
}
&relation_private_clid;
&calcul_tarification;
&insertion_logs_details;
}
}
}

en resume, pour chaque ligne de la base A, je fais une requete sur la
Base B pour savoir l'id du client qui a genere la ligne sur la base A.

Ce que je trouve dommage dans mon script, c'est que la base B ne
contient que 20 clients ... alors si je pouvais en une seul requete
charger en memoire tous les client et apres interroge cette memoire sans
passer par une requete sql, je pense que cela serait plus rapide ;=)


Commencer par corriger tout vos @ref[n] -> $ref[n], apprenez a utiliser
les placeholder, eviter d'ouvrir et de fermer sans arret votre base
de donnees, et ca devrait aller bien plus vite.

En fait, tout se passerait beaucoup mieux si toutes les infos etaient
stockes dans deux tables de la meme base de donnees. Vous avez de vraies
raisons qui vous poussent a avoir deux bases separees ?


Avatar
Mag

Commencer par corriger tout vos @ref[n] -> $ref[n], apprenez a utiliser
les placeholder, eviter d'ouvrir et de fermer sans arret votre base
de donnees, et ca devrait aller bien plus vite.

En fait, tout se passerait beaucoup mieux si toutes les infos etaient
stockes dans deux tables de la meme base de donnees. Vous avez de vraies
raisons qui vous poussent a avoir deux bases separees ?



Merci pour vos conseils, je vais deja modifier les ref.

Avoir deux bases separes:
En fait historiquement la Base A est sur un serveur précis
et la base B qui gere les "rapports" est sur un autre serveur.
Les deux serveurs ne sont pas sur le meme reseau ni meme
securisé de la meme façon (la Base A est sur des serveurs HD
et je n'interroge qu'une table alors qu'il y en a une trentaine)

Et pour compliquer le tout ;=) l'administrateur ne veux pas que
l'on touche a "sa base A"

hihi dur d'etre bricoleuse (je n'emploie pas le terme developpeuse)
quand on ne peux rien toucher

a+