Хорошо, пара вещей для таблиц журнала аудита.
Для большинства приложений мы хотим, чтобы таблицы аудита были чрезвычайно быстрыми при вставке.
Если журнал аудита действительно предназначен для диагностики или по очень нерегулярным причинам аудита, то самым быстрым критерием вставки является физическое упорядочение таблицы по времени вставки.
И это означает, что в качестве первого столбца кластеризованного индекса следует указать время аудита, например,
create unique clustered index idx_mytable on mytable(AuditDateTime, ID)
Это позволит чрезвычайно эффективно выполнять запросы выбора при вставке AuditDateTime O (log n) и O (1).
Если вы хотите просмотреть свою таблицу аудита по каждому идентификатору клиента, вам придется пойти на компромисс.
Вы можете добавить некластеризованный индекс при (CustomerID, AuditDateTime), что позволит O (log n) просматривать историю аудита для каждого клиента, однако стоимость будет заключаться в обслуживании этого некластеризованного индекса при вставке - это обслуживание будет быть O (log n) наоборот.
Однако этот штраф за время вставки может быть предпочтительнее сканирования таблицы (то есть O (n) затрат на сложность времени), которые вам придется заплатить, если у вас нет индекса на CustomerID, и это обычный запрос, который выполняется.
Поиск O (n), который блокирует таблицу для процесса записи для нерегулярного запроса, может блокировать авторов, поэтому иногда в интересах авторов быть немного медленнее, если он гарантирует, что читатели не будут блокировать свои коммиты, потому что читатели должны сканировать таблицы из-за отсутствия хорошего индекса для их поддержки ....
Добавление: если вы хотите ограничиться определенным таймфреймом, прежде всего важнее индекс AuditDateTime. И сделайте это кластеризованным, как вы вставляете в порядке AuditDateTime. Это самое важное, что вы можете сделать, чтобы ваш запрос был эффективен с самого начала.
Далее, если вы ищете самое последнее обновление для всех идентификаторов CustomerID за указанный промежуток времени, то после этого требуется полное сканирование данных, ограниченное датой вставки.
Вам нужно будет выполнить подзапрос к вашей таблице аудита, между диапазонами,
select CustomerID, max(AuditDateTime) MaxAuditDateTime
from AuditTrail
where AuditDateTime >= @begin and Audit DateTime <= @end
, а затем включите это в свой запрос select, например.
select AuditTrail.* from AuditTrail
inner join
(select CustomerID, max(AuditDateTime) MaxAuditDateTime
from AuditTrail
where AuditDateTime >= @begin and Audit DateTime <= @end
) filtration
on filtration.CustomerID = AuditTrail.CustomerID and
filtration.AuditDateTime = AuditTrail.AuditDateTime