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

LEFT OUTER JOIN explication. (postgres)

7 réponses
Avatar
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 (cost=1617924.27..1617926.35 rows=833 width=112) (actual
time=6957.730..6957.763 rows=20 loops=1)
Sort Key: panbdc.start_date, l.ref
-> HashAggregate (cost=1617871.36..1617883.86 rows=833 width=112)
(actual time=6957.523..6957.647 rows=20 loops=1)
-> Hash Join (cost=363409.35..1617846.37 rows=833 width=112)
(actual time=6856.729..6957.377 rows=20 loops=1)
Hash Cond: (("outer".ref = "inner".ref) AND ("outer".idbdc =
"inner".idbdc))
-> Hash Left Join (cost=196377.35..1284331.30 rows=16647266
width=116) (actual time=6855.771..6956.226 rows=22 loops=1)
Hash Cond: ("outer".idproduit = "inner".idproduit)
-> Merge Join (cost=195912.24..445676.34
rows=16647266 width=108) (actual time=6758.180..6858.349 rows=22 loops=1)
Merge Cond: ("outer".idbdc = "inner".idbdc)
-> Sort (cost=137223.67..137251.23 rows=11023
width=96) (actual time=106.450..106.493 rows=22 loops=1)
Sort Key: l.idbdc
-> Merge Join (cost=132496.75..136142.59
rows=11023 width=96) (actual time=1.613..106.353 rows=22 loops=1)
Merge Cond: ("outer".idproduit =
"inner".idproduit)
-> Index Scan using produit_pkey on
produit p (cost=0.00..3434.85 rows=18259 width=40) (actual
time=0.032..67.352 rows=17288 loops=1)
-> Sort (cost=132496.75..132524.30
rows=11023 width=60) (actual time=0.242..0.286 rows=22 loops=1)
Sort Key: l.idproduit
-> Index Scan using
ek_panline_idclient on panline l (cost=0.00..131756.65 rows=11023 width=60)
(actual time=0.033..0.166 rows=22 loops=1)
Index Cond: (idclient =
30563)
Filter: (qte > 0)
-> Sort (cost=58688.57..59443.68 rows=302046
width=12) (actual time=4836.062..5760.046 rows=414108 loops=1)
Sort Key: panbdc.idbdc
-> Seq Scan on panbdc
(cost=0.00..25320.72 rows=302046 width=12) (actual time=0.038..2234.801
rows=414123 loops=1)
Filter: (start_date > '2006-01-01
00:00:00'::timestamp without time zone)
-> Hash (cost=464.72..464.72 rows=157 width=12)
(actual time=97.548..97.548 rows=0 loops=1)
-> Index Scan using ek_catalogue_idsociete on
catalogue (cost=0.00..464.72 rows=157 width=12) (actual time=0.061..59.220
rows=15652 loops=1)
Index Cond: (idsociete = 9)
-> Hash (cost=167031.99..167031.99 rows=2 width=36) (actual
time=0.903..0.903 rows=0 loops=1)
-> Subquery Scan d (cost=167031.96..167031.99 rows=2
width=36) (actual time=0.698..0.850 rows=20 loops=1)
-> HashAggregate (cost=167031.96..167031.97
rows=2 width=36) (actual time=0.692..0.751 rows=20 loops=1)
-> Merge Join (cost=152026.65..163286.30
rows=749133 width=36) (actual time=0.434..0.601 rows=22 loops=1)
Merge Cond: ("outer".idbdc =
"inner".idbdc)
-> Sort (cost=17326.41..17337.74
rows=4531 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 rows=4531 width=4)
(actual time=0.107..0.127 rows=4 loops=1)
Index Cond: (idclient =
30563)
-> Sort (cost=134700.23..134782.90
rows=33067 width=36) (actual time=0.268..0.305 rows=22 loops=1)
Sort Key: panline.idbdc
-> Index Scan using
ek_panline_idclient on panline (cost=0.00..131673.98 rows=33067 width=36)
(actual time=0.099..0.202 rows=22 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+

7 réponses

Avatar
Fred Brouard - SQLpro
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 *************************
Avatar
Etienne SOBOLE
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" a écrit dans le message
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 *************************
Avatar
Fred Brouard - SQLpro
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 *************************
Avatar
Etienne SOBOLE
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" a écrit dans le message
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 *************************
Avatar
Patrick Texier
Le Sun, 9 Mar 2008 19:51:56 +0100, Etienne SOBOLE a écrit :

Salut merci de ton aide.



Pourriez-vous lire et surtout appliquer
<http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html> ?
Avatar
helios services
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
Avatar
helios services
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