Jointure multiple

Jointure multiple - SQL/NoSQL - Programmation

Marsh Posté le 12-06-2007 à 14:32:12    

Bonjour à tous.
J'ai une petite question de jointure.
J'ai un certain nombre de tables (a priori non connu).
Je sais qu'elles possèdent toutes la même clef primaire double.

 

Ce que je voudrais faire, c'est les joindre. Seulement, je ne sais pas vraiment comment je dois déclarer mes conditions de jointures.

 

Est ce que je dois faire un truc du genre :

Code :
  1. T1 INNER JOIN T2 ON T1.C1=T2.C1 AND T1.C2=T2.C2
  2.    INNER JOIN T3 ON T1.C1=T3.C1 AND T1.C2=T3.C2 AND T2.C1=T2.C3 AND T2.C2=T3.C2
  3.    ...


ou est-ce qu'il y a une notion de transitivité et que

Code :
  1. T1 INNER JOIN T2 ON T1.C1=T2.C1 AND T1.C2=T2.C2
  2.    INNER JOIN T3 ON T1.C1=T3.C1 AND T1.C2=T3.C2
  3.    ...


suffit ?

 

merci d'avance


Message édité par Pato el canardo le 12-06-2007 à 14:33:06
Reply

Marsh Posté le 12-06-2007 à 14:32:12   

Reply

Marsh Posté le 12-06-2007 à 14:38:10    

Si les tables ont la même clef primaire et si T1.C1 = T2.C1 et T1.C1 = T3.C1, alors T2.C1 = T3.C1. Donc, je pense que la deuxième solution suffit.


---------------
When it's from Finland it's good.  - Mon blog
Reply

Marsh Posté le 12-06-2007 à 14:43:17    

Si c'est la même clef primaire double pour tes 3 tables, a priori, il y a une notion de transitivité, c'est logique d'ailleurs.

Reply

Marsh Posté le 12-06-2007 à 14:48:28    

Je vous remercie.
C'est ce que je pensais, mais sans en être certain :d

Reply

Marsh Posté le 12-06-2007 à 19:00:05    

cgo2 a écrit :

Si les tables ont la même clef primaire et si T1.C1 = T2.C1 et T1.C1 = T3.C1, alors T2.C1 = T3.C1. Donc, je pense que la deuxième solution suffit.


+1
Lors d'une oppération de jointure, un index de la table jointe (ici la PK) est utilisé pour l'ensemble des tests des valeurs des tables de référence.
Par conséquent, confronter le même champ à plusieurs variables identiques de tables différentes, ça oblige le moteur à aller lire inutilement les données de toutes les tables là où une seule suffit.
 
Si l'optiiseur est bon, alors il va ignorer les tests en trop, sinon ta première requête va même être plus lente.

Reply

Marsh Posté le 12-06-2007 à 19:18:36    

Jeu de test :

Code :
  1. CREATE TABLE t1
  2. (
  3.     id numeric(18, 0) identity(1,1) NOT NULL,
  4.     [value] varchar(50) NOT NULL,
  5.     constraint pk_t1 PRIMARY KEY clustered
  6.     (
  7.         id ASC
  8.     ) WITH (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = ON, allow_page_locks = ON) ON [PRIMARY]
  9. ) ON [PRIMARY]
  10. go
  11.  
  12. CREATE TABLE t2
  13. (
  14.     id numeric(18, 0) identity(1,1) NOT NULL,
  15.     [value] varchar(50) NOT NULL,
  16.     constraint pk_t2 PRIMARY KEY clustered
  17.     (
  18.         id ASC
  19.     ) WITH (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = ON, allow_page_locks = ON) ON [PRIMARY]
  20. ) ON [PRIMARY]
  21. go
  22.  
  23. CREATE TABLE t3
  24. (
  25.     id numeric(18, 0) identity(1,1) NOT NULL,
  26.     [value] varchar(50) NOT NULL,
  27.     constraint pk_t3 PRIMARY KEY clustered
  28.     (
  29.         id ASC
  30.     ) WITH (pad_index = off, statistics_norecompute = off, ignore_dup_key = off, allow_row_locks = ON, allow_page_locks = ON) ON [PRIMARY]
  31. ) ON [PRIMARY]
  32. go
  33.  
  34. declare @i AS integer;
  35.  
  36. SET @i = 1;
  37. while @i <= 10000
  38. begin
  39.  INSERT INTO t1 ([value]) VALUES (cast(@i AS varchar(50)));
  40.  INSERT INTO t2 ([value]) VALUES (cast(@i AS varchar(50)));
  41.  INSERT INTO t3 ([value]) VALUES (cast(@i AS varchar(50)));
  42.  SELECT @i = @i + 1;
  43. end;
  44. go


 
Requête "Type 1" :

Code :
  1. SELECT t1.id, t1.value, t2.value, t3.value
  2. FROM t1
  3. INNER JOIN t2 ON t2.id = t1.id
  4. INNER JOIN t3 ON t3.id = t2.id


 
Plan d'exécution :
http://img518.imageshack.us/img518/6275/sqltype1oz6.png
 
Requête "Type 2" :

Code :
  1. SELECT t1.id, t1.value, t2.value, t3.value
  2. FROM t1
  3. INNER JOIN t2 ON t2.id = t1.id
  4. INNER JOIN t3 ON t3.id = t2.id AND t3.id = t1.id


 
Plan d'exécution :
Idem Type 1 (sous SQL Server 2005)
 
Requête "Type 3" (tentative d'optimisation en réutilisant la première table pour la jointure) :

Code :
  1. SELECT t1.id, t1.value, t2.value, t3.value
  2. FROM t1
  3. INNER JOIN t2 ON t2.id = t1.id
  4. INNER JOIN t3 ON t3.id = t1.id


 
Plan d'exécution :
Idem Type 1 (sous SQL Server 2005)
 
=> Les trois syntaxes sont équivalentes en terme d'exécution, sous SQL Server 2005 tout du moins.


Message édité par MagicBuzz le 12-06-2007 à 19:18:45
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed