LEFT OUTER JOIN explication. (postgres)

Le
Etienne SOBOLE
Salut j'ai un requete du genre

SELECT FROM table1 LEFT OUTER JOIN table2 ON table1.id = table2.id,
(SELECT ref FROM table3) AS t3 WHERE table1.ref = t2.ref

voila en gros j'ai simplifié

mais question n'est pa tellement quel résultat vais obtenir mais plutot
que veut dire la , qui se trouve juste avant le (SELECT ref

en fait ca fait quoi ce truc sa remplace une jointure ?
ma requete SELECT ref FROM table3 est tres rapide,
et sans elle tout l'ensemble est rapide,
mais la combinaison des deux morceau fait soudain ramer ma requete

A tout hasard je donne ma requete exacte ainsi que le resultat du explain
analyse que définitivement jene comprends pas !!!

SELECT l.idproduit, catalogue.prix AS pinv, l.ref, sum(l.qte) AS qte,
p.description, p.stock, l.prix, sum(l.marge) / sum(l.qte) AS marge, l.prix -
catalogue.prix AS nmarge, l.idbdc, panbdc.start_date AS ldate FROM panline
AS l INNER JOIN produit AS p ON l.idproduit = p.idproduit INNER JOIN panbdc
ON l.idbdc = panbdc.idbdc LEFT OUTER JOIN catalogue ON l.idproduit =
catalogue.idproduit AND catalogue.idsociete = 9, (SELECT ref,
max(panline.idbdc) AS idbdc FROM panline INNER JOIN panbdc ON panline.idbdc
= panbdc.idbdc WHERE panline.idclient = 30563 AND panbdc.idclient = 30563
GROUP BY ref) AS d WHERE l.ref = d.ref AND l.idbdc = d.idbdc AND l.idclient
= 30563 AND l.qte > 0 AND panbdc.start_date > '20060101' GROUP BY
l.idproduit, pinv, l.ref, p.description, p.stock, l.prix, nmarge, l.idbdc,
ldate ORDER BY ldate DESC, l.ref;



Sort (cost17924.27..1617926.35 rowsƒ3 width2) (actual
timei57.730..6957.763 rows loops=1)
Sort Key: panbdc.start_date, l.ref
-> HashAggregate (cost17871.36..1617883.86 rowsƒ3 width2)
(actual timei57.523..6957.647 rows loops=1)
-> Hash Join (cost63409.35..1617846.37 rowsƒ3 width2)
(actual timeh56.729..6957.377 rows loops=1)
Hash Cond: (("outer".ref = "inner".ref) AND ("outer".idbdc =
"inner".idbdc))
-> Hash Left Join (cost6377.35..1284331.30 rows647266
width6) (actual timeh55.771..6956.226 rows" loops=1)
Hash Cond: ("outer".idproduit = "inner".idproduit)
-> Merge Join (cost5912.24..445676.34
rows647266 width8) (actual timeg58.180..6858.349 rows" loops=1)
Merge Cond: ("outer".idbdc = "inner".idbdc)
-> Sort (cost7223.67..137251.23 rows023
width–) (actual time6.450..106.493 rows" loops=1)
Sort Key: l.idbdc
-> Merge Join (cost2496.75..136142.59
rows023 width–) (actual time=1.613..106.353 rows" loops=1)
Merge Cond: ("outer".idproduit =
"inner".idproduit)
-> Index Scan using produit_pkey on
produit p (cost=0.00..3434.85 rows259 width@) (actual
time=0.032..67.352 rows288 loops=1)
-> Sort (cost2496.75..132524.30
rows023 width`) (actual time=0.242..0.286 rows" loops=1)
Sort Key: l.idproduit
-> Index Scan using
ek_panline_idclient on panline l (cost=0.00..131756.65 rows023 width`)
(actual time=0.033..0.166 rows" loops=1)
Index Cond: (idclient =
30563)
Filter: (qte > 0)
-> Sort (costX688.57..59443.68 rows02046
width) (actual timeH36.062..5760.046 rowsA4108 loops=1)
Sort Key: panbdc.idbdc
-> Seq Scan on panbdc
(cost=0.00..25320.72 rows02046 width) (actual time=0.038..2234.801
rowsA4123 loops=1)
Filter: (start_date > '2006-01-01
00:00:00'::timestamp without time zone)
-> Hash (costF4.72..464.72 rows7 width)
(actual time—.548..97.548 rows=0 loops=1)
-> Index Scan using ek_catalogue_idsociete on
catalogue (cost=0.00..464.72 rows7 width) (actual time=0.061..59.220
rows652 loops=1)
Index Cond: (idsociete = 9)
-> Hash (cost7031.99..167031.99 rows=2 width6) (actual
time=0.903..0.903 rows=0 loops=1)
-> Subquery Scan d (cost7031.96..167031.99 rows=2
width6) (actual time=0.698..0.850 rows loops=1)
-> HashAggregate (cost7031.96..167031.97
rows=2 width6) (actual time=0.692..0.751 rows loops=1)
-> Merge Join (cost2026.65..163286.30
rowst9133 width6) (actual time=0.434..0.601 rows" loops=1)
Merge Cond: ("outer".idbdc =
"inner".idbdc)
-> Sort (cost326.41..17337.74
rowsE31 width=4) (actual time=0.153..0.160 rows=4 loops=1)
Sort Key: panbdc.idbdc
-> Index Scan using
ek_panbdc_idclient on panbdc (cost=0.00..17051.25 rowsE31 width=4)
(actual time=0.107..0.127 rows=4 loops=1)
Index Cond: (idclient =
30563)
-> Sort (cost4700.23..134782.90
rows3067 width6) (actual time=0.268..0.305 rows" loops=1)
Sort Key: panline.idbdc
-> Index Scan using
ek_panline_idclient on panline (cost=0.00..131673.98 rows3067 width6)
(actual time=0.099..0.202 rows" loops=1)
Index Cond: (idclient =
30563)
Total runtime: 6970.476 ms
(40 rows)


Alors voila je vois bien mon seq scan sur panbdc, sauf qu'il y a bien un
index sur panbdc.idbdc
Bon bref. je suis pas la galère !!!

mais surtout j'aimerai bien comprendre ce que la syntaxe d'un join avec un
virgule apres peut bine vouloir dire !

merci
a+
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Fred Brouard - SQLpro
Le #21893121
C'est un simple mélange de jointure d'avant 1992 et de jointure
normative SQL 2

bref, écrit à l'arraché donc difficile à comprendre...

Cela peut être récrit ainsi :

SELECT ...
FROM table1
LEFT OUTER JOIN table2
ON table1.id = table2.id
INNER JOIN (SELECT ref
FROM table3) AS t3
ON table1.ref = t2.ref

Et c'est tout de suite plus clair..

La sous requête :
(SELECT ref
FROM table3)
est appelée "table dérivée"....

A +

Etienne SOBOLE a écrit :
Salut j'ai un requete du genre

SELECT ... FROM table1 LEFT OUTER JOIN table2 ON table1.id = table2.id,
(SELECT ref FROM table3) AS t3 WHERE table1.ref = t2.ref

voila en gros j'ai simplifié...

mais question n'est pa tellement quel résultat vais obtenir mais plutot
que veut dire la , qui se trouve juste avant le (SELECT ref

en fait ca fait quoi ce truc sa remplace une jointure ?
ma requete SELECT ref FROM table3 est tres rapide,
et sans elle tout l'ensemble est rapide,
mais la combinaison des deux morceau fait soudain ramer ma requete...

A tout hasard je donne ma requete exacte ainsi que le resultat du explain
analyse que définitivement jene comprends pas !!!

SELECT l.idproduit, catalogue.prix AS pinv, l.ref, sum(l.qte) AS qte,
p.description, p.stock, l.prix, sum(l.marge) / sum(l.qte) AS marge, l.prix -
catalogue.prix AS nmarge, l.idbdc, panbdc.start_date AS ldate FROM panline
AS l INNER JOIN produit AS p ON l.idproduit = p.idproduit INNER JOIN panbdc
ON l.idbdc = panbdc.idbdc LEFT OUTER JOIN catalogue ON l.idproduit =
catalogue.idproduit AND catalogue.idsociete = 9, (SELECT ref,
max(panline.idbdc) AS idbdc FROM panline INNER JOIN panbdc ON panline.idbdc
= panbdc.idbdc WHERE panline.idclient = 30563 AND panbdc.idclient = 30563
GROUP BY ref) AS d WHERE l.ref = d.ref AND l.idbdc = d.idbdc AND l.idclient
= 30563 AND l.qte > 0 AND panbdc.start_date > '20060101' GROUP BY
l.idproduit, pinv, l.ref, p.description, p.stock, l.prix, nmarge, l.idbdc,
ldate ORDER BY ldate DESC, l.ref;


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort (cost17924.27..1617926.35 rowsƒ3 width2) (actual
timei57.730..6957.763 rows loops=1)
Sort Key: panbdc.start_date, l.ref
-> HashAggregate (cost17871.36..1617883.86 rowsƒ3 width2)
(actual timei57.523..6957.647 rows loops=1)
-> Hash Join (cost63409.35..1617846.37 rowsƒ3 width2)
(actual timeh56.729..6957.377 rows loops=1)
Hash Cond: (("outer".ref = "inner".ref) AND ("outer".idbdc =
"inner".idbdc))
-> Hash Left Join (cost6377.35..1284331.30 rows647266
width6) (actual timeh55.771..6956.226 rows" loops=1)
Hash Cond: ("outer".idproduit = "inner".idproduit)
-> Merge Join (cost5912.24..445676.34
rows647266 width8) (actual timeg58.180..6858.349 rows" loops=1)
Merge Cond: ("outer".idbdc = "inner".idbdc)
-> Sort (cost7223.67..137251.23 rows023
width–) (actual time6.450..106.493 rows" loops=1)
Sort Key: l.idbdc
-> Merge Join (cost2496.75..136142.59
rows023 width–) (actual time=1.613..106.353 rows" loops=1)
Merge Cond: ("outer".idproduit =
"inner".idproduit)
-> Index Scan using produit_pkey on
produit p (cost=0.00..3434.85 rows259 width@) (actual
time=0.032..67.352 rows288 loops=1)
-> Sort (cost2496.75..132524.30
rows023 width`) (actual time=0.242..0.286 rows" loops=1)
Sort Key: l.idproduit
-> Index Scan using
ek_panline_idclient on panline l (cost=0.00..131756.65 rows023 width`)
(actual time=0.033..0.166 rows" loops=1)
Index Cond: (idclient =
30563)
Filter: (qte > 0)
-> Sort (costX688.57..59443.68 rows02046
width) (actual timeH36.062..5760.046 rowsA4108 loops=1)
Sort Key: panbdc.idbdc
-> Seq Scan on panbdc
(cost=0.00..25320.72 rows02046 width) (actual time=0.038..2234.801
rowsA4123 loops=1)
Filter: (start_date > '2006-01-01
00:00:00'::timestamp without time zone)
-> Hash (costF4.72..464.72 rows7 width)
(actual time—.548..97.548 rows=0 loops=1)
-> Index Scan using ek_catalogue_idsociete on
catalogue (cost=0.00..464.72 rows7 width) (actual time=0.061..59.220
rows652 loops=1)
Index Cond: (idsociete = 9)
-> Hash (cost7031.99..167031.99 rows=2 width6) (actual
time=0.903..0.903 rows=0 loops=1)
-> Subquery Scan d (cost7031.96..167031.99 rows=2
width6) (actual time=0.698..0.850 rows loops=1)
-> HashAggregate (cost7031.96..167031.97
rows=2 width6) (actual time=0.692..0.751 rows loops=1)
-> Merge Join (cost2026.65..163286.30
rowst9133 width6) (actual time=0.434..0.601 rows" loops=1)
Merge Cond: ("outer".idbdc =
"inner".idbdc)
-> Sort (cost326.41..17337.74
rowsE31 width=4) (actual time=0.153..0.160 rows=4 loops=1)
Sort Key: panbdc.idbdc
-> Index Scan using
ek_panbdc_idclient on panbdc (cost=0.00..17051.25 rowsE31 width=4)
(actual time=0.107..0.127 rows=4 loops=1)
Index Cond: (idclient =
30563)
-> Sort (cost4700.23..134782.90
rows3067 width6) (actual time=0.268..0.305 rows" loops=1)
Sort Key: panline.idbdc
-> Index Scan using
ek_panline_idclient on panline (cost=0.00..131673.98 rows3067 width6)
(actual time=0.099..0.202 rows" loops=1)
Index Cond: (idclient =
30563)
Total runtime: 6970.476 ms
(40 rows)


Alors voila je vois bien mon seq scan sur panbdc, sauf qu'il y a bien un
index sur panbdc.idbdc
Bon bref. je suis pas la galère !!!

mais surtout j'aimerai bien comprendre ce que la syntaxe d'un join avec un
virgule apres peut bine vouloir dire !

merci
a+






--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
*********************** http://www.sqlspot.com *************************
Etienne SOBOLE
Le #21893111
Merci.
Effectivement c'est equivalent.

Mais dans ce cas comment crée t-on un index sur ce genre de requete qui peut
elle meme etre une requete complexe !!!
ma sous requete est en fait elle aussi une jointure qui renvoit deux valeurs
!!!

d'aillurs je sais meme pas quel index créer!!!
puisque pour moi tout est ok.

snif.

"Fred Brouard - SQLpro" de news: 47d40321$0$21149$
C'est un simple mélange de jointure d'avant 1992 et de jointure normative
SQL 2

bref, écrit à l'arraché donc difficile à comprendre...

Cela peut être récrit ainsi :

SELECT ...
FROM table1
LEFT OUTER JOIN table2
ON table1.id = table2.id
INNER JOIN (SELECT ref
FROM table3) AS t3
ON table1.ref = t2.ref

Et c'est tout de suite plus clair..

La sous requête :
(SELECT ref
FROM table3)
est appelée "table dérivée"....

A +

Etienne SOBOLE a écrit :
Salut j'ai un requete du genre

SELECT ... FROM table1 LEFT OUTER JOIN table2 ON table1.id = table2.id,
(SELECT ref FROM table3) AS t3 WHERE table1.ref = t2.ref

voila en gros j'ai simplifié...

mais question n'est pa tellement quel résultat vais obtenir mais plutot
que veut dire la , qui se trouve juste avant le (SELECT ref

en fait ca fait quoi ce truc sa remplace une jointure ?
ma requete SELECT ref FROM table3 est tres rapide,
et sans elle tout l'ensemble est rapide,
mais la combinaison des deux morceau fait soudain ramer ma requete...

A tout hasard je donne ma requete exacte ainsi que le resultat du explain
analyse que définitivement jene comprends pas !!!

SELECT l.idproduit, catalogue.prix AS pinv, l.ref, sum(l.qte) AS qte,
p.description, p.stock, l.prix, sum(l.marge) / sum(l.qte) AS marge,
l.prix - catalogue.prix AS nmarge, l.idbdc, panbdc.start_date AS ldate
FROM panline AS l INNER JOIN produit AS p ON l.idproduit = p.idproduit
INNER JOIN panbdc ON l.idbdc = panbdc.idbdc LEFT OUTER JOIN catalogue ON
l.idproduit = catalogue.idproduit AND catalogue.idsociete = 9, (SELECT
ref, max(panline.idbdc) AS idbdc FROM panline INNER JOIN panbdc ON
panline.idbdc = panbdc.idbdc WHERE panline.idclient = 30563 AND
panbdc.idclient = 30563 GROUP BY ref) AS d WHERE l.ref = d.ref AND
l.idbdc = d.idbdc AND l.idclient = 30563 AND l.qte > 0 AND
panbdc.start_date > '20060101' GROUP BY l.idproduit, pinv, l.ref,
p.description, p.stock, l.prix, nmarge, l.idbdc, ldate ORDER BY ldate
DESC, l.ref;


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort (cost17924.27..1617926.35 rowsƒ3 width2) (actual
timei57.730..6957.763 rows loops=1)
Sort Key: panbdc.start_date, l.ref
-> HashAggregate (cost17871.36..1617883.86 rowsƒ3 width2)
(actual timei57.523..6957.647 rows loops=1)
-> Hash Join (cost63409.35..1617846.37 rowsƒ3 width2)
(actual timeh56.729..6957.377 rows loops=1)
Hash Cond: (("outer".ref = "inner".ref) AND ("outer".idbdc
= "inner".idbdc))
-> Hash Left Join (cost6377.35..1284331.30
rows647266 width6) (actual timeh55.771..6956.226 rows" loops=1)
Hash Cond: ("outer".idproduit = "inner".idproduit)
-> Merge Join (cost5912.24..445676.34
rows647266 width8) (actual timeg58.180..6858.349 rows" loops=1)
Merge Cond: ("outer".idbdc = "inner".idbdc)
-> Sort (cost7223.67..137251.23
rows023 width–) (actual time6.450..106.493 rows" loops=1)
Sort Key: l.idbdc
-> Merge Join
(cost2496.75..136142.59 rows023 width–) (actual
time=1.613..106.353 rows" loops=1)
Merge Cond: ("outer".idproduit =
"inner".idproduit)
-> Index Scan using produit_pkey
on produit p (cost=0.00..3434.85 rows259 width@) (actual
time=0.032..67.352 rows288 loops=1)
-> Sort
(cost2496.75..132524.30 rows023 width`) (actual time=0.242..0.286
rows" loops=1)
Sort Key: l.idproduit
-> Index Scan using
ek_panline_idclient on panline l (cost=0.00..131756.65 rows023
width`) (actual time=0.033..0.166 rows" loops=1)
Index Cond: (idclient
= 30563)
Filter: (qte > 0)
-> Sort (costX688.57..59443.68 rows02046
width) (actual timeH36.062..5760.046 rowsA4108 loops=1)
Sort Key: panbdc.idbdc
-> Seq Scan on panbdc
(cost=0.00..25320.72 rows02046 width) (actual time=0.038..2234.801
rowsA4123 loops=1)
Filter: (start_date > '2006-01-01
00:00:00'::timestamp without time zone)
-> Hash (costF4.72..464.72 rows7 width)
(actual time—.548..97.548 rows=0 loops=1)
-> Index Scan using ek_catalogue_idsociete on
catalogue (cost=0.00..464.72 rows7 width) (actual
time=0.061..59.220 rows652 loops=1)
Index Cond: (idsociete = 9)
-> Hash (cost7031.99..167031.99 rows=2 width6)
(actual time=0.903..0.903 rows=0 loops=1)
-> Subquery Scan d (cost7031.96..167031.99
rows=2 width6) (actual time=0.698..0.850 rows loops=1)
-> HashAggregate (cost7031.96..167031.97
rows=2 width6) (actual time=0.692..0.751 rows loops=1)
-> Merge Join
(cost2026.65..163286.30 rowst9133 width6) (actual
time=0.434..0.601 rows" loops=1)
Merge Cond: ("outer".idbdc =
"inner".idbdc)
-> Sort (cost326.41..17337.74
rowsE31 width=4) (actual time=0.153..0.160 rows=4 loops=1)
Sort Key: panbdc.idbdc
-> Index Scan using
ek_panbdc_idclient on panbdc (cost=0.00..17051.25 rowsE31 width=4)
(actual time=0.107..0.127 rows=4 loops=1)
Index Cond: (idclient
= 30563)
-> Sort
(cost4700.23..134782.90 rows3067 width6) (actual time=0.268..0.305
rows" loops=1)
Sort Key: panline.idbdc
-> Index Scan using
ek_panline_idclient on panline (cost=0.00..131673.98 rows3067
width6) (actual time=0.099..0.202 rows" loops=1)
Index Cond: (idclient
= 30563)
Total runtime: 6970.476 ms
(40 rows)


Alors voila je vois bien mon seq scan sur panbdc, sauf qu'il y a bien un
index sur panbdc.idbdc
Bon bref. je suis pas la galère !!!

mais surtout j'aimerai bien comprendre ce que la syntaxe d'un join avec
un virgule apres peut bine vouloir dire !

merci
a+




--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
*********************** http://www.sqlspot.com *************************
Fred Brouard - SQLpro
Le #21893101
Essaye en récrivant :

SELECT l.idproduit, catalogue.prix AS pinv, l.ref,
sum(l.qte) AS qte,
p.description, p.stock, l.prix,
sum(l.marge) / sum(l.qte) AS marge,
l.prix - catalogue.prix AS nmarge, l.idbdc,
panbdc.start_date AS ldate

FROM panline AS l
INNER JOIN produit AS p
ON l.idproduit = p.idproduit
INNER JOIN panbdc
ON l.idbdc = panbdc.idbdc
LEFT OUTER JOIN catalogue
ON l.idproduit = catalogue.idproduit
INNER JOIN (SELECT ref, max(panline.idbdc) AS idbdc
FROM panline
INNER JOIN panbdc
ON panline.idbdc = panbdc.idbdc
AND panline.idclient = panbdc.idclient
WHERE panline.idclient = l.idclient
GROUP BY ref) AS d
ON l.ref = d.ref
AND l.idbdc = d.idbdc
WHERE catalogue.idsociete = 9
AND l.idclient = 30563
AND l.qte > 0
AND panbdc.start_date > '20060101'
GROUP BY l.idproduit, pinv, l.ref, p.description,
p.stock, l.prix, nmarge, l.idbdc,
ldate ORDER BY ldate DESC, l.ref;

Y a t-il des index sur toutes les jointures ?
En particulier les jointures suivantes :
a) idbdc + idclient pour les tables panline et panbdc (essayer même un
index couvrant en rajoutant en queue la colonne ref)
b) idclient + qte sur panline
c) ref, idbc sur panline
...

Y a t-il des index sur les principaux filtres ?
catalogue.idsociete
panline.idclient
planine.qte > 0
panbdc.start_date
...

A +

Etienne SOBOLE a écrit :
Salut j'ai un requete du genre

SELECT ... FROM table1 LEFT OUTER JOIN table2 ON table1.id = table2.id,
(SELECT ref FROM table3) AS t3 WHERE table1.ref = t2.ref

voila en gros j'ai simplifié...

mais question n'est pa tellement quel résultat vais obtenir mais plutot
que veut dire la , qui se trouve juste avant le (SELECT ref

en fait ca fait quoi ce truc sa remplace une jointure ?
ma requete SELECT ref FROM table3 est tres rapide,
et sans elle tout l'ensemble est rapide,
mais la combinaison des deux morceau fait soudain ramer ma requete...

A tout hasard je donne ma requete exacte ainsi que le resultat du explain
analyse que définitivement jene comprends pas !!!

SELECT l.idproduit, catalogue.prix AS pinv, l.ref, sum(l.qte) AS qte,
p.description, p.stock, l.prix, sum(l.marge) / sum(l.qte) AS marge, l.prix -
catalogue.prix AS nmarge, l.idbdc, panbdc.start_date AS ldate FROM panline
AS l INNER JOIN produit AS p ON l.idproduit = p.idproduit INNER JOIN panbdc
ON l.idbdc = panbdc.idbdc LEFT OUTER JOIN catalogue ON l.idproduit =
catalogue.idproduit AND catalogue.idsociete = 9, (SELECT ref,
max(panline.idbdc) AS idbdc FROM panline INNER JOIN panbdc ON panline.idbdc
= panbdc.idbdc WHERE panline.idclient = 30563 AND panbdc.idclient = 30563
GROUP BY ref) AS d WHERE l.ref = d.ref AND l.idbdc = d.idbdc AND l.idclient
= 30563 AND l.qte > 0 AND panbdc.start_date > '20060101' GROUP BY
l.idproduit, pinv, l.ref, p.description, p.stock, l.prix, nmarge, l.idbdc,
ldate ORDER BY ldate DESC, l.ref;


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort (cost17924.27..1617926.35 rowsƒ3 width2) (actual
timei57.730..6957.763 rows loops=1)
Sort Key: panbdc.start_date, l.ref
-> HashAggregate (cost17871.36..1617883.86 rowsƒ3 width2)
(actual timei57.523..6957.647 rows loops=1)
-> Hash Join (cost63409.35..1617846.37 rowsƒ3 width2)
(actual timeh56.729..6957.377 rows loops=1)
Hash Cond: (("outer".ref = "inner".ref) AND ("outer".idbdc =
"inner".idbdc))
-> Hash Left Join (cost6377.35..1284331.30 rows647266
width6) (actual timeh55.771..6956.226 rows" loops=1)
Hash Cond: ("outer".idproduit = "inner".idproduit)
-> Merge Join (cost5912.24..445676.34
rows647266 width8) (actual timeg58.180..6858.349 rows" loops=1)
Merge Cond: ("outer".idbdc = "inner".idbdc)
-> Sort (cost7223.67..137251.23 rows023
width–) (actual time6.450..106.493 rows" loops=1)
Sort Key: l.idbdc
-> Merge Join (cost2496.75..136142.59
rows023 width–) (actual time=1.613..106.353 rows" loops=1)
Merge Cond: ("outer".idproduit =
"inner".idproduit)
-> Index Scan using produit_pkey on
produit p (cost=0.00..3434.85 rows259 width@) (actual
time=0.032..67.352 rows288 loops=1)
-> Sort (cost2496.75..132524.30
rows023 width`) (actual time=0.242..0.286 rows" loops=1)
Sort Key: l.idproduit
-> Index Scan using
ek_panline_idclient on panline l (cost=0.00..131756.65 rows023 width`)
(actual time=0.033..0.166 rows" loops=1)
Index Cond: (idclient =
30563)
Filter: (qte > 0)
-> Sort (costX688.57..59443.68 rows02046
width) (actual timeH36.062..5760.046 rowsA4108 loops=1)
Sort Key: panbdc.idbdc
-> Seq Scan on panbdc
(cost=0.00..25320.72 rows02046 width) (actual time=0.038..2234.801
rowsA4123 loops=1)
Filter: (start_date > '2006-01-01
00:00:00'::timestamp without time zone)
-> Hash (costF4.72..464.72 rows7 width)
(actual time—.548..97.548 rows=0 loops=1)
-> Index Scan using ek_catalogue_idsociete on
catalogue (cost=0.00..464.72 rows7 width) (actual time=0.061..59.220
rows652 loops=1)
Index Cond: (idsociete = 9)
-> Hash (cost7031.99..167031.99 rows=2 width6) (actual
time=0.903..0.903 rows=0 loops=1)
-> Subquery Scan d (cost7031.96..167031.99 rows=2
width6) (actual time=0.698..0.850 rows loops=1)
-> HashAggregate (cost7031.96..167031.97
rows=2 width6) (actual time=0.692..0.751 rows loops=1)
-> Merge Join (cost2026.65..163286.30
rowst9133 width6) (actual time=0.434..0.601 rows" loops=1)
Merge Cond: ("outer".idbdc =
"inner".idbdc)
-> Sort (cost326.41..17337.74
rowsE31 width=4) (actual time=0.153..0.160 rows=4 loops=1)
Sort Key: panbdc.idbdc
-> Index Scan using
ek_panbdc_idclient on panbdc (cost=0.00..17051.25 rowsE31 width=4)
(actual time=0.107..0.127 rows=4 loops=1)
Index Cond: (idclient =
30563)
-> Sort (cost4700.23..134782.90
rows3067 width6) (actual time=0.268..0.305 rows" loops=1)
Sort Key: panline.idbdc
-> Index Scan using
ek_panline_idclient on panline (cost=0.00..131673.98 rows3067 width6)
(actual time=0.099..0.202 rows" loops=1)
Index Cond: (idclient =
30563)
Total runtime: 6970.476 ms
(40 rows)


Alors voila je vois bien mon seq scan sur panbdc, sauf qu'il y a bien un
index sur panbdc.idbdc
Bon bref. je suis pas la galère !!!

mais surtout j'aimerai bien comprendre ce que la syntaxe d'un join avec un
virgule apres peut bine vouloir dire !

merci
a+






--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
*********************** http://www.sqlspot.com *************************
Etienne SOBOLE
Le #21893091
Salut merci de ton aide.

alors byzarrement ca me dit:
ERROR: relation "l" does not exist

je sais pas pourquoi car ton exemple semble OK!!!
M'enfin bon il semble que tu ai juste mi un INNER JOIN a la place de la
virgule, et effectivement j'avais essayé moi aussi (suite a ton message
précédent)

Ca donne le meme résultat et la meme performance.
Tous les index que tu mentionnes existent (ou on existé mais n'ayant aucun
impact on été virés).

Je fini par solutionner mon probleme de façon logique plutot technique.
En gros:
ma jointure INNER JOIN panbdc ON l.idbdc = panbdc.idbdc me permettait
d'avoir la date du bon de commande.
Hors comme je cherche un max(idbdc) et que les bdc sont numeroté dans
l'ordre.

J'ai remplace ma sous requete par
SELECT ref, max(panline.idbdc) AS idbdc, max(panbdc.start_date) AS ldate
FROM panline INNER JOIN panbdc ON panline.idbdc = panbdc.idbdc WHERE
panline.idclient = 30563 AND panbdc.idclient = 30563 GROUP BY ref

recupérant par la meme occasion la fameuse date dont j'avais besoin...
du coup j'ai fait sauté ma jointure sur panbdc devenue inutile.
Et la ca va 50 fois plus vite.

Mais j'avoue que j'aurai bien voulu trouver le solution ne serait ce que
pour savoir quoi faire dans un tel cas.
Je crois que le problème ne venait pas de la sous requete mais bien de ma
jointure
INNER JOIN panbdc ON l.idbdc = panbdc.idbdc

et la c'est gros gros mystere car il existe un index sur les deux colonnes
de la jointure...

Etrange non ?
En tout cas merci.

A+
Etienne

"Fred Brouard - SQLpro" de news: 47d4247c$0$21148$
Essaye en récrivant :

SELECT l.idproduit, catalogue.prix AS pinv, l.ref,
sum(l.qte) AS qte,
p.description, p.stock, l.prix,
sum(l.marge) / sum(l.qte) AS marge,
l.prix - catalogue.prix AS nmarge, l.idbdc,
panbdc.start_date AS ldate

FROM panline AS l
INNER JOIN produit AS p
ON l.idproduit = p.idproduit
INNER JOIN panbdc
ON l.idbdc = panbdc.idbdc
LEFT OUTER JOIN catalogue
ON l.idproduit = catalogue.idproduit
INNER JOIN (SELECT ref, max(panline.idbdc) AS idbdc
FROM panline
INNER JOIN panbdc
ON panline.idbdc = panbdc.idbdc
AND panline.idclient = panbdc.idclient
WHERE panline.idclient = l.idclient
GROUP BY ref) AS d
ON l.ref = d.ref
AND l.idbdc = d.idbdc
WHERE catalogue.idsociete = 9
AND l.idclient = 30563
AND l.qte > 0
AND panbdc.start_date > '20060101'
GROUP BY l.idproduit, pinv, l.ref, p.description,
p.stock, l.prix, nmarge, l.idbdc,
ldate ORDER BY ldate DESC, l.ref;

Y a t-il des index sur toutes les jointures ?
En particulier les jointures suivantes :
a) idbdc + idclient pour les tables panline et panbdc (essayer même un
index couvrant en rajoutant en queue la colonne ref)
b) idclient + qte sur panline
c) ref, idbc sur panline
...

Y a t-il des index sur les principaux filtres ?
catalogue.idsociete
panline.idclient
planine.qte > 0
panbdc.start_date
...

A +

Etienne SOBOLE a écrit :
Salut j'ai un requete du genre

SELECT ... FROM table1 LEFT OUTER JOIN table2 ON table1.id = table2.id,
(SELECT ref FROM table3) AS t3 WHERE table1.ref = t2.ref

voila en gros j'ai simplifié...

mais question n'est pa tellement quel résultat vais obtenir mais plutot
que veut dire la , qui se trouve juste avant le (SELECT ref

en fait ca fait quoi ce truc sa remplace une jointure ?
ma requete SELECT ref FROM table3 est tres rapide,
et sans elle tout l'ensemble est rapide,
mais la combinaison des deux morceau fait soudain ramer ma requete...

A tout hasard je donne ma requete exacte ainsi que le resultat du explain
analyse que définitivement jene comprends pas !!!

SELECT l.idproduit, catalogue.prix AS pinv, l.ref, sum(l.qte) AS qte,
p.description, p.stock, l.prix, sum(l.marge) / sum(l.qte) AS marge,
l.prix - catalogue.prix AS nmarge, l.idbdc, panbdc.start_date AS ldate
FROM panline AS l INNER JOIN produit AS p ON l.idproduit = p.idproduit
INNER JOIN panbdc ON l.idbdc = panbdc.idbdc LEFT OUTER JOIN catalogue ON
l.idproduit = catalogue.idproduit AND catalogue.idsociete = 9, (SELECT
ref, max(panline.idbdc) AS idbdc FROM panline INNER JOIN panbdc ON
panline.idbdc = panbdc.idbdc WHERE panline.idclient = 30563 AND
panbdc.idclient = 30563 GROUP BY ref) AS d WHERE l.ref = d.ref AND
l.idbdc = d.idbdc AND l.idclient = 30563 AND l.qte > 0 AND
panbdc.start_date > '20060101' GROUP BY l.idproduit, pinv, l.ref,
p.description, p.stock, l.prix, nmarge, l.idbdc, ldate ORDER BY ldate
DESC, l.ref;


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort (cost17924.27..1617926.35 rowsƒ3 width2) (actual
timei57.730..6957.763 rows loops=1)
Sort Key: panbdc.start_date, l.ref
-> HashAggregate (cost17871.36..1617883.86 rowsƒ3 width2)
(actual timei57.523..6957.647 rows loops=1)
-> Hash Join (cost63409.35..1617846.37 rowsƒ3 width2)
(actual timeh56.729..6957.377 rows loops=1)
Hash Cond: (("outer".ref = "inner".ref) AND ("outer".idbdc
= "inner".idbdc))
-> Hash Left Join (cost6377.35..1284331.30
rows647266 width6) (actual timeh55.771..6956.226 rows" loops=1)
Hash Cond: ("outer".idproduit = "inner".idproduit)
-> Merge Join (cost5912.24..445676.34
rows647266 width8) (actual timeg58.180..6858.349 rows" loops=1)
Merge Cond: ("outer".idbdc = "inner".idbdc)
-> Sort (cost7223.67..137251.23
rows023 width–) (actual time6.450..106.493 rows" loops=1)
Sort Key: l.idbdc
-> Merge Join
(cost2496.75..136142.59 rows023 width–) (actual
time=1.613..106.353 rows" loops=1)
Merge Cond: ("outer".idproduit =
"inner".idproduit)
-> Index Scan using produit_pkey
on produit p (cost=0.00..3434.85 rows259 width@) (actual
time=0.032..67.352 rows288 loops=1)
-> Sort
(cost2496.75..132524.30 rows023 width`) (actual time=0.242..0.286
rows" loops=1)
Sort Key: l.idproduit
-> Index Scan using
ek_panline_idclient on panline l (cost=0.00..131756.65 rows023
width`) (actual time=0.033..0.166 rows" loops=1)
Index Cond: (idclient
= 30563)
Filter: (qte > 0)
-> Sort (costX688.57..59443.68 rows02046
width) (actual timeH36.062..5760.046 rowsA4108 loops=1)
Sort Key: panbdc.idbdc
-> Seq Scan on panbdc
(cost=0.00..25320.72 rows02046 width) (actual time=0.038..2234.801
rowsA4123 loops=1)
Filter: (start_date > '2006-01-01
00:00:00'::timestamp without time zone)
-> Hash (costF4.72..464.72 rows7 width)
(actual time—.548..97.548 rows=0 loops=1)
-> Index Scan using ek_catalogue_idsociete on
catalogue (cost=0.00..464.72 rows7 width) (actual
time=0.061..59.220 rows652 loops=1)
Index Cond: (idsociete = 9)
-> Hash (cost7031.99..167031.99 rows=2 width6)
(actual time=0.903..0.903 rows=0 loops=1)
-> Subquery Scan d (cost7031.96..167031.99
rows=2 width6) (actual time=0.698..0.850 rows loops=1)
-> HashAggregate (cost7031.96..167031.97
rows=2 width6) (actual time=0.692..0.751 rows loops=1)
-> Merge Join
(cost2026.65..163286.30 rowst9133 width6) (actual
time=0.434..0.601 rows" loops=1)
Merge Cond: ("outer".idbdc =
"inner".idbdc)
-> Sort (cost326.41..17337.74
rowsE31 width=4) (actual time=0.153..0.160 rows=4 loops=1)
Sort Key: panbdc.idbdc
-> Index Scan using
ek_panbdc_idclient on panbdc (cost=0.00..17051.25 rowsE31 width=4)
(actual time=0.107..0.127 rows=4 loops=1)
Index Cond: (idclient
= 30563)
-> Sort
(cost4700.23..134782.90 rows3067 width6) (actual time=0.268..0.305
rows" loops=1)
Sort Key: panline.idbdc
-> Index Scan using
ek_panline_idclient on panline (cost=0.00..131673.98 rows3067
width6) (actual time=0.099..0.202 rows" loops=1)
Index Cond: (idclient
= 30563)
Total runtime: 6970.476 ms
(40 rows)


Alors voila je vois bien mon seq scan sur panbdc, sauf qu'il y a bien un
index sur panbdc.idbdc
Bon bref. je suis pas la galère !!!

mais surtout j'aimerai bien comprendre ce que la syntaxe d'un join avec
un virgule apres peut bine vouloir dire !

merci
a+




--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
*********************** http://www.sqlspot.com *************************
Patrick Texier
Le #21893081
Le Sun, 9 Mar 2008 19:51:56 +0100, Etienne SOBOLE a écrit :

Salut merci de ton aide.



Pourriez-vous lire et surtout appliquer
helios services
Le #21893071
Fred Brouard - SQLpro a écrit :
C'est un simple mélange de jointure d'avant 1992 et de jointure
normative SQL 2

bref, écrit à l'arraché donc difficile à comprendre...





mais est ce plus difficile que de coder les dates depuis la reforme du
calendrier grégorien sur deux octets comme tu l' as affirmé ici j'arrive
toujours pas à comprendre comment on peut coder plus de 65536 valeurs
dans deux octets sans doute un nouveau concept l'octet élastique :-)

--
Dr Thierry HOLZ
HELIOS SERVICES
180 rue de la croix du chene
60250 HEILLES
www.openqm.com02.net
www.pick.com02.net
helios services
Le #21893061
Etienne SOBOLE a écrit :
Salut merci de ton aide.

alors byzarrement ca me dit:
ERROR: relation "l" does not exist

je sais pas pourquoi car ton exemple semble OK!!!
M'enfin bon il semble que tu ai juste mi un INNER JOIN a la place de la
virgule, et effectivement j'avais essayé moi aussi (suite a ton message
précédent)

Ca donne le meme résultat et la meme performance.
Tous les index que tu mentionnes existent (ou on existé mais n'ayant aucun
impact on été virés).

Je fini par solutionner mon probleme de façon logique plutot technique.
En gros:
ma jointure INNER JOIN panbdc ON l.idbdc = panbdc.idbdc me permettait
d'avoir la date du bon de commande.
Hors comme je cherche un max(idbdc) et que les bdc sont numeroté dans
l'ordre.

J'ai remplace ma sous requete par
SELECT ref, max(panline.idbdc) AS idbdc, max(panbdc.start_date) AS ldate
FROM panline INNER JOIN panbdc ON panline.idbdc = panbdc.idbdc WHERE
panline.idclient = 30563 AND panbdc.idclient = 30563 GROUP BY ref

recupérant par la meme occasion la fameuse date dont j'avais besoin...
du coup j'ai fait sauté ma jointure sur panbdc devenue inutile.
Et la ca va 50 fois plus vite.

Mais j'avoue que j'aurai bien voulu trouver le solution ne serait ce que
pour savoir quoi faire dans un tel cas.
Je crois que le problème ne venait pas de la sous requete mais bien de ma
jointure
INNER JOIN panbdc ON l.idbdc = panbdc.idbdc

et la c'est gros gros mystere car il existe un index sur les deux colonnes
de la jointure...

Etrange non ?
En tout cas merci.

A+



est il vraiment bizarre qu'il y ai des erreurs dans les réponses de
quelqu'un qui à affirmer en novembre pouvoir coder toute les dates
depuis la réforme du calendrier grégorien sur deux octets ?

--
Dr Thierry HOLZ
HELIOS SERVICES
180 rue de la croix du chene
60250 HEILLES
www.openqm.com02.net
www.pick.com02.net
Publicité
Poster une réponse
Anonyme