Dans SQL Server, j'essaie de créer une seule requête qui saisit une ligne et inclut les données agrégées d'une fenêtre de deux heures avant cette ligne ainsi que les données agrégées d'une ligne. fenêtre de l'heure après. Comment puis-je faire cela plus vite?Accélération de SQL Server pour appliquer des données agrégées
Les lignes sont horodatées avec une précision d'une milliseconde et ne sont pas espacées régulièrement. J'ai plus de 50 millions lignes dans ce tableau, et la requête ne semble pas être complète. Il y a des index dans beaucoup d'endroits, mais ils ne semblent pas aider. Je pensais aussi à utiliser une fonction de fenêtre, mais je ne suis pas sûr qu'il soit possible d'avoir une fenêtre coulissante avec des rangées inégalement distribuées. Aussi, pour la future fenêtre d'une heure, je ne suis pas sûr de savoir comment cela serait fait avec une fenêtre SQL.
Box est une chaîne de 10 valeurs uniques. Processus est une chaîne et a 30 valeurs uniques. La durée moyenne_ms est de 200 ms. Les erreurs représentent moins de 0,1% des données. Les 50 millions de lignes correspondent à des années de données.
select
c1.start_time,
c1.end_time,
c1.box,
c1.process,
datediff(ms,c1.start_time,c1.end_time) as duration_ms,
datepart(dw,c1.start_time) as day_of_week,
datepart(hour,c1.start_time) as hour_of_day,
c3.*,
c5.*
from metrics_table c1
cross apply
(select
avg(cast(datediff(ms,c2.start_time,c2.end_time) as numeric)) as avg_ms,
count(1) as num_process_total,
count(distinct process) as num_process_unique,
count(distinct box) as num_box_unique
from metrics_table c2
where datediff(minute,c2.start_time,c1.start_time) <= 120
and c1.start_time> c2.start_time
and c2.error_code = 0
) c3
cross apply
(select
avg(case when datediff(ms,c4.start_time,c4.end_time)>1000 then 1.0 else 0.0 end) as percent_over_thresh
from metrics_table c4
where datediff(hour,c1.start_time,c4.start_time) <= 1
and c4.start_time> c1.start_time
and c4.error_code= 0
) c5
where
c1.error_code= 0
Modifier
Version: SQL Azure 12.0
Je serais surpris si le problème de performance n'est pas à cause de vos prédicats où. Vous avez des fonctions dans votre clause where, ce qui signifie que vous devez calculer datediff pour chaque ligne. Et dans ce cas, vous le faites deux fois. Cela signifie que vous effectuez environ 100 millions de calculs de datiff. –
@Hogan J'ai essayé de faire du fenêtrage, mais je n'ai pas vu une approche qui me permettrait d'aller -2 heures à partir d'un moment si les points de données ne sont pas collectés à intervalles réguliers. Cela signifie que la différence d'une ligne à l'autre pourrait être de quelques millisecondes, pourrait être quelques secondes, pourrait être des minutes – user4446237
Yep ce n'est pas possible dans l'implémentation de SQL Server (pas de "RANGE ENTRE INTERVALLE") vous auriez à faire quelques pré-agrégation pour garantir une ligne par minute etc. Mais 'COUNT (DISTINCT ...)' n'est pas facilement compatible avec cela. –