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

[WD 9] code SQL et temps d'exe

24 réponses
Avatar
JeAn-PhI
bonjour

voici le code sql d'une req :

SELECT *
FROM T_CLIENT
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_CLIENT.CL_ID in
(
SELECT T_CLIENT.CL_ID,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID

[
union
SELECT T_CLIENT.CL_ID,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID
]

)
ORDER BY T_CLIENT.CL_RAISON_SOCIALE ASC

1 - celle-ci s'execute en moins de 7 sec (très gros volume de données)
2 - si j'enlève tout ce qui est entre [] le temps passe à + de 20 sec

qq'un saurait me dire pourquoi car il me semble qu'elle devrait être
plus rapide dans le 2ème cas

--
Cordialement JeAn-PhI

10 réponses

1 2 3
Avatar
Pierre BOUSQUET
ne serait-ce pas un problème de jointure, en effet dans la 2eme tu fais
une jointure par le WHERE, il faudrait utiliser [LEFT] JOIN ... ON

JeAn-PhI vient de nous annoncer :
bonjour

voici le code sql d'une req :

SELECT *
FROM T_CLIENT
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_CLIENT.CL_ID in
(
SELECT T_CLIENT.CL_ID,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID

[
union
SELECT T_CLIENT.CL_ID,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID
]

)
ORDER BY T_CLIENT.CL_RAISON_SOCIALE ASC

1 - celle-ci s'execute en moins de 7 sec (très gros volume de données)
2 - si j'enlève tout ce qui est entre [] le temps passe à + de 20 sec

qq'un saurait me dire pourquoi car il me semble qu'elle devrait être plus
rapide dans le 2ème cas



--
Pierre BOUSQUET

" Ne me dites pas que ce problème est difficile.
S'il n'était pas difficile, ce ne serait pas un problème. "
Avatar
JeAn-PhI
Pierre BOUSQUET avait écrit le 31/01/2007 :
ne serait-ce pas un problème de jointure, en effet dans la 2eme tu fais une
jointure par le WHERE, il faudrait utiliser [LEFT] JOIN ... ON



[CUT]
dans les 2 cas la jointure est dans le where et je ne veux pas de left
join car je veux uniquement les client qui ont une facture et ou un
avoir

--
Cordialement JeAn-PhI
Avatar
elecoest
On 31 jan, 15:51, JeAn-PhI wrote:
bonjour

voici le code sql d'une req :

SELECT *
FROM T_CLIENT
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_CLIENT.CL_ID in
(
SELECT T_CLIENT.CL_ID,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID

[
union
SELECT T_CLIENT.CL_ID,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID
]

)
ORDER BY T_CLIENT.CL_RAISON_SOCIALE ASC

1 - celle-ci s'execute en moins de 7 sec (très gros volume de données)
2 - si j'enlève tout ce qui est entre [] le temps passe à + de 20 sec

qq'un saurait me dire pourquoi car il me semble qu'elle devrait être
plus rapide dans le 2ème cas



Rappels d'optimisation de requete :
- un exist est plus rapide qu'un in
- un union all est plus rapide qu'un union

Dans ta requete:
- on va parcourir toutes les factures par client et faire la somme de
celles-ci,
- on va parcourir tous les avoirs par client et faire la somme de ceux-
ci,
- on va fusionner les 2 résultats
- on va parcourir les clients et tester l'existence dans l'ensemble ci-
dessus.

Vu que tu ne testes que la présence du client, le group by ne sert à
rien. A la rigeur le group by servirait si tu devais tester le solde
client afin qu'il soit non nul (=0) mais là il faudrait passé par un
outer join.

Un sql que je te proposerais (pas testé mais l'idée est là):

SELECT T_CLIENT.*
FROM T_CLIENT
left outer join T_FACTURE on T_CLIENT.CL_ID = T_FACTURE.CL_ID
and T_FACTURE.FA_DATE BETWEEN
{pDateDeb} AND {pDateFin}
left outer join T_AVOIR_FACTURE on T_AVOIR_FACTURE.CL_ID =
T_CLIENT.CL_ID
and
T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and (T_AVOIR_FACTURE.CL_ID is not null or T_FACTURE.CL_ID is not
null)

Ok çà ne répond pas à ta question mais j'espère t'avoir donné u ne
autre piste.
Avatar
Emprin, Frederic
Bonjour,

moi j'aurais fait comme ca :
le but etant d'avoir les client qui ont des avir ou des facture :

SELECT *
FROM T_CLIENT
LEFT JOIN T_FACTURE ON T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}

LEFT JOIN T_AVOIR_FACTURE ON T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}

WHERE
T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND (T_FACTURE.CL_ID is not null or T_AVOIR_FACTURE.CL_ID is not null)

ORDER BY T_CLIENT.CL_RAISON_SOCIALE ASC

Bon dev
@+


"JeAn-PhI" a écrit dans le message de news:

bonjour

voici le code sql d'une req :

SELECT *
FROM T_CLIENT
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_CLIENT.CL_ID in
(
SELECT T_CLIENT.CL_ID,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID

[
union
SELECT T_CLIENT.CL_ID,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID
]

)
ORDER BY T_CLIENT.CL_RAISON_SOCIALE ASC

1 - celle-ci s'execute en moins de 7 sec (très gros volume de données)
2 - si j'enlève tout ce qui est entre [] le temps passe à + de 20 sec

qq'un saurait me dire pourquoi car il me semble qu'elle devrait être plus
rapide dans le 2ème cas

--
Cordialement JeAn-PhI




Avatar
Pierre BOUSQUET
et comme cela

SELECT *
FROM T_CLIENT
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_CLIENT.CL_ID in
(
SELECT T_CLIENT.CL_ID
FROM T_FACTURE
WHERE T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
HAVING SUM(T_FACTURE.TOTAL)>0
GROUP BY T_CLIENT.CL_ID

union
SELECT T_CLIENT.CL_ID,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE
WHERE T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
HAVING SUM(T_AVOIR_FACTURE.TOTAL)>0
group by T_CLIENT.CL_ID
)

JeAn-PhI a formulé la demande :
Pierre BOUSQUET avait écrit le 31/01/2007 :
ne serait-ce pas un problème de jointure, en effet dans la 2eme tu fais une
jointure par le WHERE, il faudrait utiliser [LEFT] JOIN ... ON



[CUT]
dans les 2 cas la jointure est dans le where et je ne veux pas de left join
car je veux uniquement les client qui ont une facture et ou un avoir



--
Pierre BOUSQUET

" Ne me dites pas que ce problème est difficile.
S'il n'était pas difficile, ce ne serait pas un problème. "
Avatar
JeAn-PhI
JeAn-PhI a utilisé son clavier pour écrire :
bonjour

voici le code sql d'une req :

SELECT *
FROM T_CLIENT
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_CLIENT.CL_ID in
(
SELECT T_CLIENT.CL_ID,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID

[
union
SELECT T_CLIENT.CL_ID,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID
]

)
ORDER BY T_CLIENT.CL_RAISON_SOCIALE ASC

1 - celle-ci s'execute en moins de 7 sec (très gros volume de données)
2 - si j'enlève tout ce qui est entre [] le temps passe à + de 20 sec

qq'un saurait me dire pourquoi car il me semble qu'elle devrait être plus
rapide dans le 2ème cas



je vais regarder les différentes proposition et je vous tiens au
courant

mon but étant bien de récupérer les client qui ont des fatures et ou
des avoir

--
Cordialement JeAn-PhI
Avatar
Pierre BOUSQUET
dans ce cas pas besoin du HAVING dans la derniere reponse que je t'ai
faite

JeAn-PhI a exposé le 31/01/2007 :
JeAn-PhI a utilisé son clavier pour écrire :
bonjour

voici le code sql d'une req :

SELECT *
FROM T_CLIENT
WHERE T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_CLIENT.CL_ID in
(
SELECT T_CLIENT.CL_ID,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID

[
union
SELECT T_CLIENT.CL_ID,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID
]

)
ORDER BY T_CLIENT.CL_RAISON_SOCIALE ASC

1 - celle-ci s'execute en moins de 7 sec (très gros volume de données)
2 - si j'enlève tout ce qui est entre [] le temps passe à + de 20 sec

qq'un saurait me dire pourquoi car il me semble qu'elle devrait être plus
rapide dans le 2ème cas



je vais regarder les différentes proposition et je vous tiens au courant

mon but étant bien de récupérer les client qui ont des fatures et ou des
avoir



--
Pierre BOUSQUET

" Ne me dites pas que ce problème est difficile.
S'il n'était pas difficile, ce ne serait pas un problème. "
Avatar
JeAn-PhI
JeAn-PhI avait écrit le 31/01/2007 :
bonjour

voici le code sql d'une req :


[CUT]

pour elecoest -> renvoi le résultat que je souhaite avec une rapidité
phénoménale - de 1 sec (il me reste encore du chemin à faire en SQL)

pour Frederic -> idem

pour Pierre -> renvoi le bon résultat mais en + de 2 sec


pour abuser un peu est ce qu'il y aurait moyen d'optimiser celle ci :

SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE
union
SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
AND T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID, CL_RAISON_SOCIALE
order by T_CLIENT.CL_RAISON_SOCIALE

le but étant d'avoir un liste qui contient 1 enreg pour un client avec
la somme des facture et ou 1 enreg pour le même client avec la somme
des avoirs
CLIENT1 SommeFacture
CLIENT1 SommeAvoir
CLIENT2 SommeFacture
CLIENT3 SommeAvoir
...

--
Cordialement JeAn-PhI
Avatar
Emprin, Frederic
Bonsoir

pourquoi ne pas faire cela :

SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total facture,
SUM(T_AVOIR_FACTURE.TOTAL) AS TotalAvoir

FROM T_CLIENT

LEFT JOIN T_FACTURE ON T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}

LEFT JOIN T_AVOIR_FACTURE ON T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}

WHERE T_T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND (T_FACTURE.CL_ID is not null or T_AVOIR_FACTURE.CL_ID is not null)

GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE
order by T_CLIENT.CL_RAISON_SOCIALE

le but étant d'avoir un liste qui contient 1 enreg pour un client avec
la somme des facture et ou 1 enreg pour le même client avec la somme
des avoirs
CLIENT1 SommeFacture SommeAvoir
CLIENT2 SommeFacture SommeAvoir
CLIENT3 SommeFacture SommeAvoir

les sommes sont soit >0 toutes les deux soit une seule
on enleve les clients qui non rien

mais on a une ligne par client
maintenant si tu veux vraiement ton resultat sur une ligne fac et une ligne
avoir
tu peux la faire par l'union comme tu la fait

SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total facture,

FROM T_CLIENT

LEFT JOIN T_FACTURE ON T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}

WHERE T_T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND (T_FACTURE.CL_ID is not null )

GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE

UNION

SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_AVOIR_FACTURE.TOTAL) AS TotalAvoir

FROM T_CLIENT

LEFT JOIN T_AVOIR_FACTURE ON T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}

WHERE T_T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND (T_AVOIR_FACTURE.CL_ID is not null)

GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE

order by T_CLIENT.CL_RAISON_SOCIALE

Bon dev
@+

"JeAn-PhI" a écrit dans le message de news:

JeAn-PhI avait écrit le 31/01/2007 :
bonjour

voici le code sql d'une req :


[CUT]

pour elecoest -> renvoi le résultat que je souhaite avec une rapidité
phénoménale - de 1 sec (il me reste encore du chemin à faire en SQL)

pour Frederic -> idem

pour Pierre -> renvoi le bon résultat mais en + de 2 sec


pour abuser un peu est ce qu'il y aurait moyen d'optimiser celle ci :

SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE
union
SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
AND T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID, CL_RAISON_SOCIALE
order by T_CLIENT.CL_RAISON_SOCIALE

le but étant d'avoir un liste qui contient 1 enreg pour un client avec la
somme des facture et ou 1 enreg pour le même client avec la somme des
avoirs
CLIENT1 SommeFacture
CLIENT1 SommeAvoir
CLIENT2 SommeFacture
CLIENT3 SommeAvoir
...

--
Cordialement JeAn-PhI




Avatar
Pierre BOUSQUET
Bravo elecoest !
50% de temps gagné

JeAn-PhI a formulé ce mercredi :
JeAn-PhI avait écrit le 31/01/2007 :
bonjour

voici le code sql d'une req :


[CUT]

pour elecoest -> renvoi le résultat que je souhaite avec une rapidité
phénoménale - de 1 sec (il me reste encore du chemin à faire en SQL)

pour Frederic -> idem

pour Pierre -> renvoi le bon résultat mais en + de 2 sec


pour abuser un peu est ce qu'il y aurait moyen d'optimiser celle ci :

SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_FACTURE.TOTAL) AS Total
FROM T_FACTURE, T_CLIENT
WHERE T_CLIENT.CL_ID = T_FACTURE.CL_ID
AND T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
AND T_FACTURE.FA_DATE BETWEEN {pDateDeb} AND {pDateFin}
GROUP BY T_CLIENT.CL_ID, CL_RAISON_SOCIALE
union
SELECT T_CLIENT.CL_ID,
T_CLIENT.CL_RAISON_SOCIALE AS CL_RAISON_SOCIALE,
SUM(T_AVOIR_FACTURE.TOTAL) AS Total
from T_AVOIR_FACTURE, T_CLIENT
where T_AVOIR_FACTURE.CL_ID = T_CLIENT.CL_ID
AND T_CLIENT.CL_RAISON_SOCIALE LIKE {pClientRS}%
and T_AVOIR_FACTURE.AF_DATE between {pDateDeb} AND {pDateFin}
group by T_CLIENT.CL_ID, CL_RAISON_SOCIALE
order by T_CLIENT.CL_RAISON_SOCIALE

le but étant d'avoir un liste qui contient 1 enreg pour un client avec la
somme des facture et ou 1 enreg pour le même client avec la somme des avoirs
CLIENT1 SommeFacture
CLIENT1 SommeAvoir
CLIENT2 SommeFacture
CLIENT3 SommeAvoir
...



--
Pierre BOUSQUET

" Ne me dites pas que ce problème est difficile.
S'il n'était pas difficile, ce ne serait pas un problème. "
1 2 3