Bonjour à tous,

Ci-dessous 3 syntaxes différentes pour réaliser la même opération.

Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/* REQUETE 1 */
SELECT p.id_produit,p.nom,pcb.code_barre 
FROM produit p 
left outer join (
      select id_produit, max(ISNULL(code_barre, 0)) as code_barre 
      from Produit_code_barre
      group by id_produit
) pcb on pcb.id_produit = p.id_produit
where  p.id_type_produit = 1
	and p.id_produit < 5000
 
/* REQUETE 2 */
select p.id_produit,p.nom,pcb.code_barre from 
produit p 
outer apply (
		select top 1 sub_pcb.id_produit, sub_pcb.code_barre
		from Produit_code_barre sub_pcb 
		where p.id_produit=sub_pcb.id_produit
		order by sub_pcb.id_produit, sub_pcb.code_barre
) pcb
where  p.id_type_produit = 1
	and p.id_produit < 5000
 
/* REQUETE 3 */
SELECT id_produit,nom,code_barre 
FROM (
	SELECT p.id_produit,p.nom,pcb.code_barre, RANK() OVER (PARTITION BY p.id_produit ORDER BY pcb.code_barre DESC) AS RANK
	FROM produit p 
	LEFT OUTER JOIN Produit_code_barre pcb
		ON pcb.id_produit = p.id_produit
	WHERE p.id_type_produit = 1
		AND p.id_produit < 5000
) T
WHERE RANK = 1

Après une rapide analyse, quand je lance les 3 requêtes dans l'estimateur de plan d'exécution, il m'annonce les consommations prévisionnelles suivantes :

- Requête 1 : 15 %
- Requête 2 : 67 %
- Requête 3 : 18 %

J'aurai pourtant dit, comme ça à l'instinct que la 3 ème requête serait la meilleure...

Qu'en est-il en terme de lecture/écriture/cpu ? Cette répartition est-elle fiable avec 10 000 exécutions simultanées par exemples ?

Pourquoi cet ordre là finalement ?

A quoi sert cette 2ème syntaxe (et plus particulièrement l'instruction OUTER APPLY) si elle peut être remplacée par au moins 2 syntaxes plus performantes ?

Merci d'avance pour vos suggestions/analyses