J'avoir une table avec des rangées de 20m, et chaque rangée possède 3 colonnes: time
, id
, et value
. Pour chacun id
et time
, il y a un value
pour le statut. Je veux connaître les valeurs de plomb et de retard d'un certain time
pour un spécifique id
.
J'ai utilisé deux méthodes pour y parvenir. Une méthode utilise join et une autre méthode utilise les fonctions de fenêtre lead / lag avec un index clusterisé sur time
et id
.
J'ai comparé les performances de ces deux méthodes par le temps d'exécution. La méthode de jointure prend 16,3 secondes et la méthode de fonction de fenêtre prend 20 secondes, sans compter le temps de création de l'index. Cela m'a surpris car la fonction window semble être avancée alors que les méthodes de jointure sont en force brute.
Voici le code des deux méthodes:
Créer un index
create clustered index id_time
on tab1 (id,time)
Méthode Join
select a1.id,a1.time
a1.value as value,
b1.value as value_lag,
c1.value as value_lead
into tab2
from tab1 a1
left join tab1 b1
on a1.id = b1.id
and a1.time-1= b1.time
left join tab1 c1
on a1.id = c1.id
and a1.time+1 = c1.time
Statistiques d'E / S générées à l'aide de SET STATISTICS TIME, IO ON
:
Voici le plan d'exécution de la méthode join
Méthode de fonction de fenêtre
select id, time, value,
lag(value,1) over(partition by id order by id,time) as value_lag,
lead(value,1) over(partition by id order by id,time) as value_lead
into tab2
from tab1
(La commande uniquement par time
enregistre 0,5 seconde.)
Voici le plan d'exécution de la méthode de la fonction Window
Statistiques d'E / S
[
J'ai vérifié les données sample_orig_month_1999
et il semble que les données brutes soient bien ordonnées par id
et time
. Est-ce la raison de la différence de performances?
Il semble que la méthode de jointure ait plus de lectures logiques que la méthode de fonction de fenêtre, alors que le temps d'exécution pour la première est en fait inférieur. Est-ce parce que le premier a un meilleur parallélisme?
J'aime la méthode de la fonction de fenêtre en raison du code concis, existe-t-il un moyen de l'accélérer pour ce problème spécifique?
J'utilise SQL Server 2016 sur Windows 10 64 bits.