jeu. 07 janvier 2016, 15h03
jcriv
France
atoutfox.public.association
Re: SELECT ... Join vs In ()
Re,
Piqué par la curiosité, j'ai voulu vérifier avec un petit prg pour tester en vfp. Si mes test sont exacts, la meilleure solution, y compris en fox, est de mettre le maximum dans la jointure :
Tests faits avec de grosses tables (en dbf), le résultat des requêtes atteignant env. 330.000 enreg.
Sur ma machine, voici les ordres de grandeur :
Moy innerand 0,86830 (la jointure contient la condition)
Moy innerwhere 0,87360 (jointure + clause where)
Moy incursorind 1,34040 (select in, avec présélection de la select du in dans un curseur, et avec création d'un index)
Moy incursor 1,35150 (select in, avec présélection de la select du in dans un curseur non indexé)
Moy insimple 1,48030 (select in)
Voici le prg avec mes tables :
CLEAR
CREATE CURSOR _res (type c(15), temps N(7,5))
FOR i = 1 TO 10
innerwhere()
NEXT
FOR i = 1 TO 10
innerand()
NEXT
FOR i = 1 TO 10
incursor()
NEXT
FOR i = 1 TO 10
incursorindex()
NEXT
FOR i = 1 TO 10
insimple()
NEXT
SELECT _Res
INSERT INTO _Res (type, temps) ;
SELECT "Moy " + type, AVG(temps) as temps FROM _res group by type order by 2
BROWSE NOWAIT
cc = ""
SCAN
cc = m.cc + Type + CHR(9)+ STR(temps, 7,5) + CHR(13) + CHR(10)
ENDSCAN
_cliptext = m.cc
RETURN
PROCEDURE innerwhere
? SYS(1104)
s=SECONDS()
SELECT s.* ;
FROM sequence s INNER JOIN emissio e ;
ON s.id_emissio = e.id ;
WHERE e.eddatemi>{01/01/2014} ;
INTO CURSOR _tmp
INSERT INTO _Res (temps, Type) VALUES (SECONDS()-m.s, "innerwhere")
USE IN _Tmp
RETURN
PROCEDURE innerand
? SYS(1104)
s=SECONDS()
SELECT s.* ;
FROM sequence s INNER JOIN emissio e ;
ON s.id_emissio = e.id ;
and e.eddatemi>{01/01/2014} ;
into cursor _tmp
INSERT INTO _Res (temps, Type) VALUES (SECONDS()-m.s, "innerand")
USE IN _tmp
RETURN
PROCEDURE insimple
? SYS(1104)
s=SECONDS()
SELECT s.* ;
FROM sequence s ;
WHERE s.id_emissio in (SELECT e.id FROM emissio e WHERE e.eddatemi>{01/01/2014}) ;
into cursor _tmp
INSERT INTO _Res (temps, Type) VALUES (SECONDS()-m.s, "insimple")
USE IN _tmp
RETURN
PROCEDURE incursor
? SYS(1104)
s=SECONDS()
SELECT e.id FROM emissio e WHERE e.eddatemi>{01/01/2014} into CURSOR _Emi
SELECT s.* ;
FROM sequence s ;
WHERE s.id_emissio in (SELECT id FROM _Emi) ;
into cursor _tmp
INSERT INTO _Res (temps, Type) VALUES (SECONDS()-m.s, "incursor")
USE IN _tmp
USE IN _Emi
RETURN
PROCEDURE incursorindex
? SYS(1104)
s=SECONDS()
SELECT e.id FROM emissio e WHERE e.eddatemi>{01/01/2014} into CURSOR _Emi
INDEX on id TAG id
SELECT s.* ;
FROM sequence s ;
WHERE s.id_emissio in (SELECT id FROM _Emi) ;
into cursor _tmp
INSERT INTO _Res (temps, Type) VALUES (SECONDS()-m.s, "incursorindex")
USE IN _tmp
USE IN _Emi
RETURN
Cordialement,
JC
Journal
FoxInCloud (Th. Nivelet) pense que ce message est la bonne réponse ou qu'il est utile
Permalink : http://www.atoutfox.org/nntp.asp?ID=0000017102