OVH Cloud OVH Cloud

[SQL] l'UNION fait la FORCE !!

15 réponses
Avatar
Arnaud [lwa]
Bonjour,

Une constatation simple sur 2 requ=EAtes impliquant pour=20
l'exemple 1 table de 700000 enregistrements et 2 tables de=20
400000 enregeistrements :

R=E9sultat obtenu au bout de 170 Secondes

SELECT MARA.MATNR AS Article,=20
MAKTX AS Designation,=20
MTART AS Type,=20
MATKL AS GM,=20
BISMT AS Ancien_No,=20
MFRPN AS Reference,=20
MFRNR AS Fab_Frs,=20
BWKEY AS Division,=20
BKLAS AS CV

FROM (MARA INNER JOIN MAKT=20
ON MARA.MATNR =3D MAKT.MATNR)
=20
INNER JOIN MBEW=20
ON MARA.MATNR =3D=20
MBEW.MATNR

WHERE MAKTX Like [Critere]=20
or MFRPN Like [Critere];

10 réponses

1 2
Avatar
Jessy Sempere [MVP]
Salut

Et donc, c'est quoi ton problème ???

Si ce n'est que ça me paraît bien long... ;-))

@+
Jessy Sempere - Access MVP

------------------------------------
Site @ccess : http://access.jessy.free.fr/
Pour l'efficacité de tous :
http://users.skynet.be/mpfa/
------------------------------------
"Arnaud [lwa]" a écrit dans le message news:
2bc0d01c468b8$10e1c840$
Bonjour,

Une constatation simple sur 2 requêtes impliquant pour
l'exemple 1 table de 700000 enregistrements et 2 tables de
400000 enregeistrements :

Résultat obtenu au bout de 170 Secondes

SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR MBEW.MATNR

WHERE MAKTX Like [Critere]
or MFRPN Like [Critere];
Avatar
Arnaud [lwa]
oups désolé message parti trop vite avec l'interface
WEB....et avant qu'elle apparaisse ....
je continue donc :
alors que la requête UNION ci-dessous
retourne le même résultat en 18 secondes au lieu de 170.

SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR = MBEW.MATNR

WHERE MAKTX Like [Critere]

UNION SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR = MBEW.MATNR

WHERE MFRPN Like [Critere];



ps : DISTINCT inutile dans une requête UNION,
mais pas de différence notoire entre les temps dexécution
d'un SELECT et par rapport à un SELECT DISTINCT.

--
Bonne journée
Arnaud
http://memoaccess.free.fr



-----Message d'origine-----
Bonjour,

Une constatation simple sur 2 requêtes impliquant pour
l'exemple 1 table de 700000 enregistrements et 2 tables
de

400000 enregeistrements :

Résultat obtenu au bout de 170 Secondes

SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR =
MBEW.MATNR

WHERE MAKTX Like [Critere]
or MFRPN Like [Critere];


.



Avatar
Raymond [mvp]
Bonjour Arnaud et Jessy

C'est un non problème qui doit appeler une non réponse, mais comme nous
sommes curieux notre réponse va appeler une question qui va créer un
problème, donc on part à zéro.
--
@+
Raymond Access MVP
http://access.seneque.free.fr/
http://access.vba.free.fr/
http://access2003.free.fr/
http://users.skynet.be/mpfa/ pour débuter sur le forum


"Jessy Sempere [MVP]" a écrit dans le message de
news:cd08p0$856$
Salut

Et donc, c'est quoi ton problème ???

Si ce n'est que ça me paraît bien long... ;-))

@+
Jessy Sempere - Access MVP


Avatar
Jessy Sempere [MVP]
Re,

Bon en toute ignorance, je dirais qu'il y a moins de propriété dans
une requête union en plus c'est du spécifique SQL, donc c'est
sûrement traité différement par Access, et donc plus rapidement
mais ça fait quand même un gros écart ????

Sinon juste pour info, inutile de spécifier les alias dans ta 2ème
instruction Select...
(fallait bien que je dise un truc dont je suis sûr... ;-)))

@+
Jessy Sempere - Access MVP

------------------------------------
Site @ccess : http://access.jessy.free.fr/
Pour l'efficacité de tous :
http://users.skynet.be/mpfa/
------------------------------------
"Arnaud [lwa]" a écrit dans le message news:
2bc2301c468b9$873f7d60$
oups désolé message parti trop vite avec l'interface
WEB....et avant qu'elle apparaisse ....
je continue donc :
alors que la requête UNION ci-dessous
retourne le même résultat en 18 secondes au lieu de 170.

SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR = MBEW.MATNR

WHERE MAKTX Like [Critere]

UNION SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR = MBEW.MATNR

WHERE MFRPN Like [Critere];



ps : DISTINCT inutile dans une requête UNION,
mais pas de différence notoire entre les temps dexécution
d'un SELECT et par rapport à un SELECT DISTINCT.

--
Bonne journée
Arnaud
http://memoaccess.free.fr
Avatar
Arnaud [lwa]
Re JESSY

-----Message d'origine-----
Sinon juste pour info, inutile de spécifier les alias
dans ta 2ème

instruction Select...
(fallait bien que je dise un truc dont je suis sûr... ;-




oui en me relisant, j'avais vu que j'avais recopié les
alias (pas simple de poster depuis l'interface web !!)
: bien sûr, on ne les met que sur la permière requete.

Mais c'est impressionnant la différence entre
WHERE champ1 =X OR champ2 = X

et

WHERE champ1 =X
UNION
WHERE champ2 = X

j'essaye de comprendre pourquoi personne ne me l'avait
jamais dit !!

a+
Arnaud

Avatar
Jessy Sempere [MVP]
Re,


Mais c'est impressionnant la différence entre
WHERE champ1 =X OR champ2 = X
et
WHERE champ1 =X
UNION
WHERE champ2 = X
j'essaye de comprendre pourquoi personne ne me l'avait
jamais dit !!


Tout simplement parce que tu es le spécialiste des découvertes... ;-)))
Par contre je veux bien pour testé chez moi que tu m'envois
la base avec les 3 tables et les deux requêtes par contre sous
Access 97 si possible biensûr... ;-)

--
@+
Jessy Sempere - Access MVP

------------------------------------
Site @ccess : http://access.jessy.free.fr/
Pour l'efficacité de tous :
http://users.skynet.be/mpfa/
------------------------------------

Avatar
Arnaud [lwa]
-----Message d'origine-----
Par contre je veux bien pour testé chez moi que tu
m'envois

la base avec les 3 tables et les deux requêtes par contre
sous

Access 97 si possible biensûr... ;-)



ok je te l'envoie... mais tu te chargeras de rajouter des
données car actuellement, la base fait 165 Mo ;-)))

à toute !
Arnaud

Avatar
Michel Walsh
Salut,


La raison du problème semble toute simple. La jointure est effectuée AVANT
le where. Donc, il y a comparaisons entre plusieurs champs, "l'explosion" du
join (une possibilité de 400 000 au carré, j'apelle cela une explosion)
est emmagasinée temporairement, et de cette explosion, établie, on ne
conserve, par sélection de critère WHERE, que quelques individus. Ressources
mal utilisées!

Il serait plus astucieux, dans ce cas, de faire le critère AVANT la
jointure:

SELECT * FROM makt WHERE maktx LIKE [Critere]

dans une requête, S1, pareil pour mfrpn LIKE [Critere], dans une requête
S2 (ou la même requête S1, si c'est de la même table). Cette requête
implique maitenant beaucoup MOINS que 400 000 enregistrement, probablement
100 000, non (mon estimé est basé sur des hypothèses un peu farfelues, mais
également de par les chiffres que tu avances: 100k = 400k * ( 170 /
(18*0.5) ) ^0.5) ?

Utiliser S1 ( et S2 si applicable) au lieu des tables originales, avec une
syntaxe voisine de la première requête, sans sa condition WHERE maintenant
inutile, devrait alors redonner un temps d'exécution d'une dizaine de
secondes (deux fois moins long que la requête UNION), voire mieux (surtout
si les requêtes S1 et S2 retournent en deça de 100k-enregistrements).


Si tu utilises MS SQL Server, tu peux faire remonter le critère du genre:
champ=constante
DANS la clause ON appropriée du join, cela aura le même effet. Avec Jet, on
ne peut pas, car Jet repasse derrière nous et redescend ce critère dans le
WHERE, à moins de procéder par requêtes cascadées, comme proposé, ou par
tables virtuelles (ce qui est la même chose, dans le fond).


Espérant être utile,
Vanderghast, Access MVP


"Arnaud [lwa]" wrote in message
news:2bc2301c468b9$873f7d60$
oups désolé message parti trop vite avec l'interface
WEB....et avant qu'elle apparaisse ....
je continue donc :
alors que la requête UNION ci-dessous
retourne le même résultat en 18 secondes au lieu de 170.

SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR = MBEW.MATNR

WHERE MAKTX Like [Critere]

UNION SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR = MBEW.MATNR

WHERE MFRPN Like [Critere];



ps : DISTINCT inutile dans une requête UNION,
mais pas de différence notoire entre les temps dexécution
d'un SELECT et par rapport à un SELECT DISTINCT.

--
Bonne journée
Arnaud
http://memoaccess.free.fr



-----Message d'origine-----
Bonjour,

Une constatation simple sur 2 requêtes impliquant pour
l'exemple 1 table de 700000 enregistrements et 2 tables
de

400000 enregeistrements :

Résultat obtenu au bout de 170 Secondes

SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR >MBEW.MATNR

WHERE MAKTX Like [Critere]
or MFRPN Like [Critere];


.



Avatar
Jessy Sempere [MVP]
Bonjour

Encore une fois tu m'impressionnes par tes explications... ;-)

Petite question :
Et si on spécifiait la jointure directement dans la clause WHERE,
qu'est ce que ça donnerait en terme de performance ???

Genre :
SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM MARA, MAKT, MBEW

WHERE MARA.MATNR = MAKT.MATNR AND
MARA.MATNR = MBEW.MATNR AND
(MAKTX Like [Critere] OR MFRPN Like [Critere]);

@+
Jessy Sempere - Access MVP

------------------------------------
Site @ccess : http://access.jessy.free.fr/
Pour l'efficacité de tous :
http://users.skynet.be/mpfa/
------------------------------------
"Michel Walsh" a écrit dans le message news:
eh$$
Salut,


La raison du problème semble toute simple. La jointure est effectuée AVANT
le where. Donc, il y a comparaisons entre plusieurs champs, "l'explosion" du
join (une possibilité de 400 000 au carré, j'apelle cela une explosion)
est emmagasinée temporairement, et de cette explosion, établie, on ne
conserve, par sélection de critère WHERE, que quelques individus. Ressources
mal utilisées!

Il serait plus astucieux, dans ce cas, de faire le critère AVANT la
jointure:

SELECT * FROM makt WHERE maktx LIKE [Critere]

dans une requête, S1, pareil pour mfrpn LIKE [Critere], dans une requête
S2 (ou la même requête S1, si c'est de la même table). Cette requête
implique maitenant beaucoup MOINS que 400 000 enregistrement, probablement
100 000, non (mon estimé est basé sur des hypothèses un peu farfelues, mais
également de par les chiffres que tu avances: 100k = 400k * ( 170 /
(18*0.5) ) ^0.5) ?

Utiliser S1 ( et S2 si applicable) au lieu des tables originales, avec une
syntaxe voisine de la première requête, sans sa condition WHERE maintenant
inutile, devrait alors redonner un temps d'exécution d'une dizaine de
secondes (deux fois moins long que la requête UNION), voire mieux (surtout
si les requêtes S1 et S2 retournent en deça de 100k-enregistrements).


Si tu utilises MS SQL Server, tu peux faire remonter le critère du genre:
champ=constante
DANS la clause ON appropriée du join, cela aura le même effet. Avec Jet, on
ne peut pas, car Jet repasse derrière nous et redescend ce critère dans le
WHERE, à moins de procéder par requêtes cascadées, comme proposé, ou par
tables virtuelles (ce qui est la même chose, dans le fond).


Espérant être utile,
Vanderghast, Access MVP


"Arnaud [lwa]" wrote in message
news:2bc2301c468b9$873f7d60$
oups désolé message parti trop vite avec l'interface
WEB....et avant qu'elle apparaisse ....
je continue donc :
alors que la requête UNION ci-dessous
retourne le même résultat en 18 secondes au lieu de 170.

SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR = MBEW.MATNR

WHERE MAKTX Like [Critere]

UNION SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR = MBEW.MATNR

WHERE MFRPN Like [Critere];



ps : DISTINCT inutile dans une requête UNION,
mais pas de différence notoire entre les temps dexécution
d'un SELECT et par rapport à un SELECT DISTINCT.

--
Bonne journée
Arnaud
http://memoaccess.free.fr



-----Message d'origine-----
Bonjour,

Une constatation simple sur 2 requêtes impliquant pour
l'exemple 1 table de 700000 enregistrements et 2 tables
de

400000 enregeistrements :

Résultat obtenu au bout de 170 Secondes

SELECT MARA.MATNR AS Article,
MAKTX AS Designation,
MTART AS Type,
MATKL AS GM,
BISMT AS Ancien_No,
MFRPN AS Reference,
MFRNR AS Fab_Frs,
BWKEY AS Division,
BKLAS AS CV

FROM (MARA INNER JOIN MAKT
ON MARA.MATNR = MAKT.MATNR)

INNER JOIN MBEW
ON MARA.MATNR > >MBEW.MATNR

WHERE MAKTX Like [Critere]
or MFRPN Like [Critere];


.







Avatar
Arnaud [lwa]
Bonjour Michel,
Merci pour ces précieuses informations.
J'imprimerai ton message en arrivant à la maison pour
mieux le décortiquer.
je suis toujours en train d'essayer de fournir à Jessy une
base avec quelques exemples, mais mon ordi est en train de
fumer en voulant vider une partie des tables par un
delete * from mbew where matnr not in (select matnr from
mara;) et ça s'éternise, il devait y avoir plus rapide...

Pour l'estimation, on verra mais un reboot de l'ordi sera
nécessaire parce que là, j'ai l'impression de travailler
avec un 386 sx 12 !!

je vous tiendrai au courant si la requête supression veut
bien se terminer un jour ....

A bientôt
Arnaud
-----Message d'origine-----
Salut,


La raison du problème semble toute simple. La jointure
est effectuée AVANT

le where. Donc, il y a comparaisons entre plusieurs
champs, "l'explosion" du

join (une possibilité de 400 000 au carré, j'apelle
cela une explosion)

est emmagasinée temporairement, et de cette explosion,
établie, on ne

conserve, par sélection de critère WHERE, que quelques
individus. Ressources

mal utilisées!

Il serait plus astucieux, dans ce cas, de faire le
critère AVANT la

jointure:

SELECT * FROM makt WHERE maktx LIKE [Critere]

dans une requête, S1, pareil pour mfrpn LIKE [Critere],
dans une requête

S2 (ou la même requête S1, si c'est de la même table).
Cette requête

implique maitenant beaucoup MOINS que 400 000
enregistrement, probablement

100 000, non (mon estimé est basé sur des hypothèses un
peu farfelues, mais

également de par les chiffres que tu avances: 100k =
400k * ( 170 /

(18*0.5) ) ^0.5) ?

Utiliser S1 ( et S2 si applicable) au lieu des tables
originales, avec une

syntaxe voisine de la première requête, sans sa condition
WHERE maintenant

inutile, devrait alors redonner un temps d'exécution
d'une dizaine de

secondes (deux fois moins long que la requête UNION),
voire mieux (surtout

si les requêtes S1 et S2 retournent en deça de 100k-
enregistrements).



Si tu utilises MS SQL Server, tu peux faire remonter le
critère du genre:

champ=constante
DANS la clause ON appropriée du join, cela aura le même
effet. Avec Jet, on

ne peut pas, car Jet repasse derrière nous et redescend
ce critère dans le

WHERE, à moins de procéder par requêtes cascadées, comme
proposé, ou par

tables virtuelles (ce qui est la même chose, dans le
fond).



Espérant être utile,
Vanderghast, Access MVP



1 2