Cela ressemble à un scénario idéal pour une vue indexée, qui vous permet de payer des calculs et des agrégats au moment de l'écriture au lieu du temps de la requête.
CREATE VIEW dbo.MyIndexedView
WITH SCHEMABINDING
AS
SELECT Enroll_Date, UserID, RawCount = COUNT_BIG(*)
FROM dbo.UserTable
GROUP BY Enroll_Date, UserID;
GO
CREATE UNIQUE CLUSTERED INDEX CIX_miv ON dbo.MyIndexedView(Enroll_Date, UserID);
Cela prendra un certain temps à créer et nécessitera bien sûr une maintenance tout au long de toutes les opérations DML, tout comme un index sur la table de base.
Maintenant, la requête par rapport à cette vue serait assez similaire - chaque ligne de la vue représente maintenant un combo utilisateur / date distinct, de sorte que le chiffre peut être calculé par un seul COUNT (*), tandis que le nombre total de lignes dans la table de base est déjà partiellement agrégées pour vous, il vous suffit maintenant de les additionner en utilisant SUM par date:
SELECT Enroll_Date,
[Record #] = SUM(RawCount),
[User #] = COUNT(*)
FROM dbo.MyIndexedView WITH (NOEXPAND)
GROUP BY Enroll_Date;
Ajout d'un indice NOEXPAND, après avoir rappelé ceci et cela .
Je peux vous dire sans aucun doute que cette requête sera plus rapide que votre requête actuelle (mais pas de combien), sauf dans les rares cas où vous avez exactement un utilisateur pour chaque date (auquel cas la même quantité de données aura à lire) et les colonnes que nous connaissons sont les seules colonnes de l'index de la table de base. Nous ne pouvons pas vous dire si cet accroissement des performances au moment de la lecture vaut le travail supplémentaire qui affectera la partie écriture de votre charge de travail - vous devrez le tester pour mesurer le compromis (aucun index n'est gratuit).
Et si vous utilisez fréquemment les mêmes clauses WHERE communes contre Enroll_Date pour des plages spécifiques et bien définies (par exemple, le trimestre ou l'année en cours à ce jour), vous pouvez ajouter des index filtrés correspondants qui réduisent encore plus les E / S (mais il y a toujours un troquer).
Vous pouvez également envisager de placer un index cluster sur la table de base. Cela ne semble pas être l'un de ces cas d'utilisation très rares qui bénéficient d'un tas.