OVH Cloud OVH Cloud

Meilleure écriture d'une requête

3 réponses
Avatar
Oliv'
Bonjour,
Les 2 requetes suivantes semblent renvoyer les mêmes données .
Laquelle et la meilleure selon vous ?
----1ère version

SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
FROM SI_Sinistres inner join SI_Garanties_Eval on
SI_Sinistres.Sin_Sinistre_id = SI_Garanties_Eval.Singaev_Sinistre_id
inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id =
PP_Contrats.Pol_Contrat_id
inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id =
lastsit.Pol_Cie_id
AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
AND lastsit.Pol_LastSituation=1
inner join PP_Contrats_Transports on PolC9_Contrat_id =
lastsit.Pol_Contrat_id
WHERE
(SI_Garanties_Eval.Singaev_DteEval between '17/03/2005' and '22/03/2005')
AND (PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1)

union

SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
FROM SI_Sinistres inner join SI_Garanties_Affect on Singaaf_Sinistre_id =
SI_Sinistres.Sin_Sinistre_id
inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id =
PP_Contrats.Pol_Contrat_id
inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id =
lastsit.Pol_Cie_id
AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
AND lastsit.Pol_LastSituation=1
inner join PP_Contrats_Transports on PolC9_Contrat_id =
lastsit.Pol_Contrat_id
WHERE
(SI_Garanties_Affect.Singaaf_DteAffect between '17/03/2005' and
'22/03/2005')
AND (PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1)

-----2 ème version
SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
FROM SI_Sinistres FULL OUTER JOIN SI_Garanties_Eval on
SI_Sinistres.Sin_Sinistre_id = SI_Garanties_Eval.Singaev_Sinistre_id
FULL OUTER JOIN SI_Garanties_Affect on Singaaf_Sinistre_id =
SI_Sinistres.Sin_Sinistre_id
inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id =
PP_Contrats.Pol_Contrat_id
inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id =
lastsit.Pol_Cie_id
AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
AND lastsit.Pol_LastSituation=1
inner join PP_Contrats_Transports on PolC9_Contrat_id =
lastsit.Pol_Contrat_id
WHERE
((SI_Garanties_Eval.Singaev_DteEval between '17/03/2005' and '22/03/2005')
or (SI_Garanties_Affect.Singaaf_DteAffect between '17/03/2005' and
'22/03/2005') )
AND (PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1)

Merci d'avance
Oliv'

3 réponses

Avatar
Fred BROUARD
1) il faut comparer les plan de requête et notamment voir le cout des IO.
Faites SET STATISTICS IO ON et lancer les 2 requêtes.

2) a vue de nez la seconde

3) plus claire :

SELECT DISTINCT S.Sin_Sinistre_id

FROM SI_Sinistres S

FULL OUTER JOIN SI_Garanties_Eval GE
ON S.Sin_Sinistre_id = GE.Singaev_Sinistre_id

FULL OUTER JOIN SI_Garanties_Affect GA
ON GA.Singaaf_Sinistre_id = S.Sin_Sinistre_id

INNER join PP_Contrats C1
ON S.Sin_Contrat_id = C1.Pol_Contrat_id

INNER JOIN PP_Contrats C2 --lastsit
ON C1.Pol_Cie_id = C2.Pol_Cie_id
AND C1.Pol_Contrat = C2.Pol_Contrat

INNER JOIN PP_Contrats_Transports CT
ON CT.PolC9_Contrat_id = C2.Pol_Contrat_id

WHERE C2.Pol_LastSituation = 1
AND ( GE.Singaev_DteEval BETWEEN '20050317' and '20050322'
or GA.Singaaf_DteAffect BETWEEN '20050317' and '20050322')
AND CT.PolC9_EDI_ENVOI_PROVISIONS = 1

A +

--
Frédéric BROUARD, MVP SQL Server. Expert SQL / spécialiste Delphi, web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
************************ www.datasapiens.com *************************

Oliv' a écrit:
Bonjour,
Les 2 requetes suivantes semblent renvoyer les mêmes données .
Laquelle et la meilleure selon vous ?
----1ère version

SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
FROM SI_Sinistres inner join SI_Garanties_Eval on
SI_Sinistres.Sin_Sinistre_id = SI_Garanties_Eval.Singaev_Sinistre_id
inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id =
PP_Contrats.Pol_Contrat_id
inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id =
lastsit.Pol_Cie_id
AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
AND lastsit.Pol_LastSituation=1
inner join PP_Contrats_Transports on PolC9_Contrat_id =
lastsit.Pol_Contrat_id
WHERE
(SI_Garanties_Eval.Singaev_DteEval between '17/03/2005' and '22/03/2005')
AND (PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1)

union

SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
FROM SI_Sinistres inner join SI_Garanties_Affect on Singaaf_Sinistre_id =
SI_Sinistres.Sin_Sinistre_id
inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id =
PP_Contrats.Pol_Contrat_id
inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id =
lastsit.Pol_Cie_id
AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
AND lastsit.Pol_LastSituation=1
inner join PP_Contrats_Transports on PolC9_Contrat_id =
lastsit.Pol_Contrat_id
WHERE
(SI_Garanties_Affect.Singaaf_DteAffect between '17/03/2005' and
'22/03/2005')
AND (PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1)

-----2 ème version
SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
FROM SI_Sinistres FULL OUTER JOIN SI_Garanties_Eval on
SI_Sinistres.Sin_Sinistre_id = SI_Garanties_Eval.Singaev_Sinistre_id
FULL OUTER JOIN SI_Garanties_Affect on Singaaf_Sinistre_id =
SI_Sinistres.Sin_Sinistre_id
inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id =
PP_Contrats.Pol_Contrat_id
inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id =
lastsit.Pol_Cie_id
AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
AND lastsit.Pol_LastSituation=1
inner join PP_Contrats_Transports on PolC9_Contrat_id =
lastsit.Pol_Contrat_id
WHERE
((SI_Garanties_Eval.Singaev_DteEval between '17/03/2005' and '22/03/2005')
or (SI_Garanties_Affect.Singaaf_DteAffect between '17/03/2005' and
'22/03/2005') )
AND (PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1)

Merci d'avance
Oliv'




Avatar
Oliv'
Bonjour Fred,

Fred BROUARD wrote:
1) il faut comparer les plan de requête et notamment voir le cout des
IO. Faites SET STATISTICS IO ON et lancer les 2 requêtes.



résultat des stats la première (avec le union) Compte d'analyses 910
lectures logiques 5667
la seconde Compte d'analyses 2481 lectures logiques 10223


2) a vue de nez la seconde



c'est donc la première !, j'aurais penché aussi pour l'autre.
3) plus claire :

SELECT DISTINCT S.Sin_Sinistre_id

FROM SI_Sinistres S

FULL OUTER JOIN SI_Garanties_Eval GE
ON S.Sin_Sinistre_id = GE.Singaev_Sinistre_id

FULL OUTER JOIN SI_Garanties_Affect GA
ON GA.Singaaf_Sinistre_id = S.Sin_Sinistre_id

INNER join PP_Contrats C1
ON S.Sin_Contrat_id = C1.Pol_Contrat_id

INNER JOIN PP_Contrats C2 --lastsit
ON C1.Pol_Cie_id = C2.Pol_Cie_id
AND C1.Pol_Contrat = C2.Pol_Contrat

INNER JOIN PP_Contrats_Transports CT
ON CT.PolC9_Contrat_id = C2.Pol_Contrat_id

WHERE C2.Pol_LastSituation = 1
AND ( GE.Singaev_DteEval BETWEEN '20050317' and '20050322'
or GA.Singaaf_DteAffect BETWEEN '20050317' and '20050322')
AND CT.PolC9_EDI_ENVOI_PROVISIONS = 1



Si j'avais eu un LEFT JOIN PP_Contrats C2 le fait de mettre le
C2.Pol_LastSituation = 1 dans la clause WHERE donnerait'il le même résultat
?

A +



Merci beaucoup pour tes excellents conseils.
Oliv'

Oliv' a écrit:
Bonjour,
Les 2 requetes suivantes semblent renvoyer les mêmes données .
Laquelle et la meilleure selon vous ?
----1ère version

SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
FROM SI_Sinistres inner join SI_Garanties_Eval on
SI_Sinistres.Sin_Sinistre_id = SI_Garanties_Eval.Singaev_Sinistre_id
inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id >> PP_Contrats.Pol_Contrat_id
inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id >> lastsit.Pol_Cie_id
AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
AND lastsit.Pol_LastSituation=1
inner join PP_Contrats_Transports on PolC9_Contrat_id >> lastsit.Pol_Contrat_id
WHERE
(SI_Garanties_Eval.Singaev_DteEval between '17/03/2005' and
'22/03/2005') AND
(PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1) union

SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
FROM SI_Sinistres inner join SI_Garanties_Affect on
Singaaf_Sinistre_id = SI_Sinistres.Sin_Sinistre_id
inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id >> PP_Contrats.Pol_Contrat_id
inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id >> lastsit.Pol_Cie_id
AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
AND lastsit.Pol_LastSituation=1
inner join PP_Contrats_Transports on PolC9_Contrat_id >> lastsit.Pol_Contrat_id
WHERE
(SI_Garanties_Affect.Singaaf_DteAffect between '17/03/2005' and
'22/03/2005')
AND (PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1)

-----2 ème version
SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
FROM SI_Sinistres FULL OUTER JOIN SI_Garanties_Eval on
SI_Sinistres.Sin_Sinistre_id = SI_Garanties_Eval.Singaev_Sinistre_id
FULL OUTER JOIN SI_Garanties_Affect on Singaaf_Sinistre_id >> SI_Sinistres.Sin_Sinistre_id
inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id >> PP_Contrats.Pol_Contrat_id
inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id >> lastsit.Pol_Cie_id
AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
AND lastsit.Pol_LastSituation=1
inner join PP_Contrats_Transports on PolC9_Contrat_id >> lastsit.Pol_Contrat_id
WHERE
((SI_Garanties_Eval.Singaev_DteEval between '17/03/2005' and
'22/03/2005') or (SI_Garanties_Affect.Singaaf_DteAffect between
'17/03/2005' and '22/03/2005') )
AND (PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1)

Merci d'avance
Oliv'




Avatar
bruno reiter [MVP]
en fait ça dépend du nombre d'enregs des tables et de l'indexation.
attention au format des dates pour les tests.

br

"Oliv'" <(supprimerceci) wrote in message
news:
Bonjour Fred,

Fred BROUARD wrote:
> 1) il faut comparer les plan de requête et notamment voir le cout des
> IO. Faites SET STATISTICS IO ON et lancer les 2 requêtes.

résultat des stats la première (avec le union) Compte d'analyses 910
lectures logiques 5667
la seconde Compte d'analyses 2481 lectures logiques 10223


> 2) a vue de nez la seconde

c'est donc la première !, j'aurais penché aussi pour l'autre.
> 3) plus claire :
>
> SELECT DISTINCT S.Sin_Sinistre_id
>
> FROM SI_Sinistres S
>
> FULL OUTER JOIN SI_Garanties_Eval GE
> ON S.Sin_Sinistre_id = GE.Singaev_Sinistre_id
>
> FULL OUTER JOIN SI_Garanties_Affect GA
> ON GA.Singaaf_Sinistre_id = S.Sin_Sinistre_id
>
> INNER join PP_Contrats C1
> ON S.Sin_Contrat_id = C1.Pol_Contrat_id
>
> INNER JOIN PP_Contrats C2 --lastsit
> ON C1.Pol_Cie_id = C2.Pol_Cie_id
> AND C1.Pol_Contrat = C2.Pol_Contrat
>
> INNER JOIN PP_Contrats_Transports CT
> ON CT.PolC9_Contrat_id = C2.Pol_Contrat_id
>
> WHERE C2.Pol_LastSituation = 1
> AND ( GE.Singaev_DteEval BETWEEN '20050317' and '20050322'
> or GA.Singaaf_DteAffect BETWEEN '20050317' and '20050322')
> AND CT.PolC9_EDI_ENVOI_PROVISIONS = 1
>
Si j'avais eu un LEFT JOIN PP_Contrats C2 le fait de mettre le
C2.Pol_LastSituation = 1 dans la clause WHERE donnerait'il le même


résultat
?

> A +

Merci beaucoup pour tes excellents conseils.
Oliv'
>
> Oliv' a écrit:
>> Bonjour,
>> Les 2 requetes suivantes semblent renvoyer les mêmes données .
>> Laquelle et la meilleure selon vous ?
>> ----1ère version
>>
>> SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
>> FROM SI_Sinistres inner join SI_Garanties_Eval on
>> SI_Sinistres.Sin_Sinistre_id = SI_Garanties_Eval.Singaev_Sinistre_id
>> inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id > >> PP_Contrats.Pol_Contrat_id
>> inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id > >> lastsit.Pol_Cie_id
>> AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
>> AND lastsit.Pol_LastSituation=1
>> inner join PP_Contrats_Transports on PolC9_Contrat_id > >> lastsit.Pol_Contrat_id
>> WHERE
>> (SI_Garanties_Eval.Singaev_DteEval between '17/03/2005' and
>> '22/03/2005') AND
>> (PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1) union
>>
>> SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
>> FROM SI_Sinistres inner join SI_Garanties_Affect on
>> Singaaf_Sinistre_id = SI_Sinistres.Sin_Sinistre_id
>> inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id > >> PP_Contrats.Pol_Contrat_id
>> inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id > >> lastsit.Pol_Cie_id
>> AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
>> AND lastsit.Pol_LastSituation=1
>> inner join PP_Contrats_Transports on PolC9_Contrat_id > >> lastsit.Pol_Contrat_id
>> WHERE
>> (SI_Garanties_Affect.Singaaf_DteAffect between '17/03/2005' and
>> '22/03/2005')
>> AND (PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1)
>>
>> -----2 ème version
>> SELECT DISTINCT SI_Sinistres.Sin_Sinistre_id
>> FROM SI_Sinistres FULL OUTER JOIN SI_Garanties_Eval on
>> SI_Sinistres.Sin_Sinistre_id = SI_Garanties_Eval.Singaev_Sinistre_id
>> FULL OUTER JOIN SI_Garanties_Affect on Singaaf_Sinistre_id > >> SI_Sinistres.Sin_Sinistre_id
>> inner join PP_Contrats on SI_Sinistres.Sin_Contrat_id > >> PP_Contrats.Pol_Contrat_id
>> inner join PP_Contrats lastsit on PP_Contrats.Pol_Cie_id > >> lastsit.Pol_Cie_id
>> AND PP_Contrats.Pol_Contrat = lastsit.Pol_Contrat
>> AND lastsit.Pol_LastSituation=1
>> inner join PP_Contrats_Transports on PolC9_Contrat_id > >> lastsit.Pol_Contrat_id
>> WHERE
>> ((SI_Garanties_Eval.Singaev_DteEval between '17/03/2005' and
>> '22/03/2005') or (SI_Garanties_Affect.Singaaf_DteAffect between
>> '17/03/2005' and '22/03/2005') )
>> AND (PP_Contrats_Transports.PolC9_EDI_ENVOI_PROVISIONS=1)
>>
>> Merci d'avance
>> Oliv'