Походит на идеальный сценарий для индексированного представления, которое позволяет вам платить за вычисления и агрегаты во время записи вместо времени запроса.
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);
Это займет некоторое время для создания и, конечно, потребует сопровождения во всех операциях DML, точно так же, как индекс в базовой таблице.
Теперь запрос к этому представлению будет очень похожим - каждая строка в представлении теперь представляет отдельную комбинацию пользователя / даты, так что цифра может быть вычислена по одному COUNT (*), тогда как общее количество строк в базовой таблице равно уже частично агрегированы для вас, теперь вам просто нужно добавить их, используя SUM на дату:
SELECT Enroll_Date,
[Record #] = SUM(RawCount),
[User #] = COUNT(*)
FROM dbo.MyIndexedView WITH (NOEXPAND)
GROUP BY Enroll_Date;
Добавлена подсказка NOEXPAND, после запоминания этого и этого .
Я могу безоговорочно сказать вам, что этот запрос будет быстрее, чем ваш текущий запрос (но не на сколько), за исключением редкого случая, когда у вас есть ровно один пользователь на каждую дату (в этом случае тот же объем данных будет иметь для чтения), и столбцы, о которых мы знаем, являются единственными столбцами в индексе базовой таблицы. О том, стоит ли повышение производительности во время чтения дополнительной работы, которая повлияет на часть записи вашей рабочей нагрузки, мы не можем вам сказать - вам придется протестировать ее, чтобы измерить компромисс (никакой индекс не является бесплатным).
И если вы часто используете одни и те же общие предложения WHERE для Enroll_Date для конкретных, четко определенных диапазонов (скажем, текущего квартала или года до даты), вы можете добавить соответствующие отфильтрованные индексы, которые еще больше уменьшат этот ввод / вывод (но всегда есть компромисс).
Вы можете также рассмотреть возможность размещения кластеризованного индекса на базовой таблице. Похоже, это не один из тех очень редких вариантов использования, которые выигрывают от кучи.