Calcul moyen en éliminant les valeurs Top 10% et Bas 10% à l'aide de T-SQL

J'ai besoin de calculer la durée moyenne d'une de nos procédures stockées en cours d'exécution. Par exemple, la durée (en secondes) de SP est: 1,30,2,5,2,15,35,7,3,4,2,1,2,40

Je dois éliminer les 10 premiers appels (appels rapides) et les 10 derniers appels (appels lents) et calculer la moyenne sur le rest.

Y a-t-il une meilleure approche pour minimiser les pertes de performances, car cela doit se faire sur un énorme set de données de façon régulière?

L'approche que je connais est:

Éliminer les 10% d'loggings les plus fréquents en utilisant la requête suivante, ce qui entraîne deux valeurs (1,1)

SELECT TOP 10 PERCENT WITH TIES value FROM #t order by value asc 

le fond 10% donne (35,40),

 SELECT TOP 10 PERCENT WITH TIES value FROM #t order by value desc 

Après avoir éliminé ces valeurs (1,1,35 & 40), la moyenne va être de 7.

Une option qui fonctionne relativement bien dans mes tests (less de 1 seconde avec 300 000 lignes, jusqu'à 12 secondes avec 10 millions de lignes):

 declare @tot int = (select count(*) from #MyData) ; with cte as (select Data, ROW_NUMBER() over (order by data) RN from #MyData) select avg(Data) from cte where rn between @tot/10 and 9*@tot/10 

Édité pour assurer une "coupe de cheveux" uniforme

 Declare @YourTable table (Seconds int) Insert Into @YourTable values (1),(30),(2),(5),(2),(15),(35),(7),(3),(4),(2),(1),(2),(40) Select AvgSeconds = avg(Seconds) From ( Select * ,Dec1 = NTile(10) over (Order By Seconds) ,Dec2 = NTile(10) over (Order By Seconds Desc) From @YourTable ) A Where Dec1 between 2 and 9 and Dec2 between 2 and 9 

Résultats

 AvgSeconds 7