Нет, их нет. Любое отслеживание «Последнее обновление в» может привести к серьезной проблеме производительности, поскольку все обновления из всех транзакций будут пытаться обновить одну запись, отслеживающую «Последнее обновление в». Это фактически означало бы, что только одна транзакция может обновлять таблицу в любой момент, и все остальные транзакции должны ждать, пока первая из них будет зафиксирована . Полная Сериализация. Число администраторов / разработчиков, готовых смириться с таким снижением производительности только для того, чтобы знать, когда произошло последнее обновление, вероятно, невелико.
Таким образом, вы застряли, чтобы справиться с этим через пользовательский код. Это означает триггеры, поскольку альтернатива (обнаружение по записям журнала) является прерогативой, зарезервированной только для репликации транзакций (или это альтернативное эго CDC ). Имейте в виду, что если вы попытаетесь отследить его через столбец «последнее обновление в», то вы столкнетесь именно с проблемой сериализации, упомянутой выше. Если параллелизм обновления важен, вам придется использовать механизм очереди (триггер использует INSERT, а затем процесс объединяет вставленные значения, чтобы сформулировать «последнее обновление в»). Не пытайтесь обманывать с каким-нибудь «умным» решением, например, подкрадываться к текущей личности или искать sys.dm_db_index_usage_stats . А также столбец «updated_at» для каждой записи, как у временных меток Rails,
Есть ли «легкая» альтернатива? На самом деле он есть, но трудно сказать, будет ли он работать для вас, и трудно понять его правильно: уведомления о запросах . Query Notification делает именно это, он настроит уведомление, если какие-либо данные изменились, и вам нужно обновить ваш запрос. Хотя большинство разработчиков знакомы только с его воплощением .Net как SqlDependency, Query Notification можно использовать как долговременный постоянный механизм для обнаружения изменений данных. По сравнению с истинным отслеживанием изменений он будет действительно легковесным, а его семантика ближе к вашим потребностям (что-то, что-нибудь изменилось, поэтому вам нужно повторно выполнить запрос).
Но, в конце концов, на вашем месте я действительно пересмотрю свои предположения и вернусь к чертежной доске. Возможно, вы можете использовать доставку журналов или репликацию для настройки базы данных отчетов на другом сервере. Что я прочитал между строк, так это то, что вам нужен правильный ETL-канал и аналитическое хранилище данных ...
Похоже, я опоздал на игру на два года, но на самом деле есть довольно легкий способ сделать то, что вы просите.
Есть два механизма SQL Server, которые могут вам помочь. Ваше окончательное решение может быть гибридом двух.
Отслеживание изменений . SQL Server имеет возможность размещать определенные таблицы под наблюдением, записывать только те строки, которые были изменены (по значению их первичного ключа), и какие это были изменения (Вставить, Обновить или Удалить). После настройки обнаружения изменений для набора таблиц облегченный запрос может сообщить вам, были ли внесены какие-либо изменения в таблицу с момента последней проверки. Накладные расходы примерно такие же, как и на поддержание дополнительного простого индекса.
Rowversion / timestamp . Это 8-байтовый тип столбца varbinary (преобразуемый в BigInt), который увеличивается по всей базе данных всякий раз, когда строка, содержащая его, вставляется или обновляется (это не помогает при удалении). Если вы проиндексировали эти столбцы, вы могли бы легко определить, изменились ли данные строки, сравнив значение MAX (отметка времени) с его значением с момента последней оценки. Поскольку значение монотонно увеличивается, это даст вам надежное указание на то, что данные изменились, если новое значение больше, чем в прошлый раз, когда вы его проверяли.
источник
Если источник только для вставки, укажите
IDENTITY
столбец. Когда вы выполняете передачу данных, вы записываете наибольшее значение, записанное. Во время следующей передачи вам нужно только запросить значения, которые были больше, чем во время предыдущей передачи. Мы делаем это для передачи записей журнала в хранилище данных.Для обновляемых строк добавьте «грязный» флаг. Он будет иметь три значения - чистый, грязный и удаленный. В повседневных запросах нужно будет пропустить строки с установленным флагом «удалено». Это будет дорого в обслуживании, тестировании и во время выполнения. После большого запроса вы упоминаете, что все строки, помеченные для удаления, должны быть удалены, а флаг сброшен для всех остальных. Это не будет хорошо масштабироваться.
Более легкой альтернативой для сбора данных изменений является отслеживание изменений . Он не скажет вам, какие значения изменились, только то, что строка изменилась с момента последнего запроса. Встроенные функции облегчают поиск измененных значений и управление отслеживанием. Мы успешно использовали CT для обработки около 100 000 изменений в день в таблице 100 000 000 строк.
Уведомления о запросах действуют еще выше - на уровне набора результатов. Концептуально это похоже на определение представления. Если SQL Server обнаруживает, что любая строка, возвращенная через это представление, изменилась, он запускает сообщение для приложения. Не указано, сколько строк изменилось или какие столбцы. Есть только простые сообщения, говорящие «что-то случилось». Это зависит от приложения, чтобы узнать и отреагировать. Практически это намного сложнее, чем вы можете себе представить. Существуют ограничения на то, как запрос может быть определен, и уведомление может запускаться для условий, отличных от измененных данных. Когда уведомление срабатывает, оно удаляется. Если дальнейшая интересующая деятельность произойдет впоследствии, дальнейшее сообщение не будет отправлено.
В контексте вопроса OP, QN будет иметь преимущество, заключающееся в том, что он требует минимальных накладных расходов и требует небольших затрат времени выполнения. Это может быть значительное усилие, чтобы установить и поддерживать строгий режим подписки-сообщения-реагирования. Поскольку таблица данных велика, вероятно, в ней будут частые изменения, а это означает, что уведомление может срабатывать в большинстве циклов обработки. Поскольку нет указаний на то, что изменилась инкрементная обработка дельт, будет невозможно, как это было бы с CT или CDC. Накладные расходы из-за ложных срабатываний являются утомительными, но даже в худшем случае дорогой запрос не нужно выполнять чаще, чем в настоящее время.
источник
SqlTableDependency
SqlTableDependency - это компонент реализации высокого уровня для доступа к уведомлениям, содержащим значения записей таблицы в базе данных SQL Server.
SqlTableDependency - это общий компонент C #, используемый для получения уведомлений при изменении содержимого указанной таблицы базы данных.
В чем разница с .NET SqlDepenency?
Основное отличие состоит в том, что SqlTableDependency отправляет события, содержащие значения для вставленной, измененной или удаленной записи, а также операцию DML (вставка / удаление / обновление), выполняемую в таблице: SqlDepenency не сообщает, какие данные были изменены в таблицы базы данных, они только говорят, что что-то изменилось.
Посмотрите на проект GITHUB .
источник
Если ожидаемые обновления влияют на индекс (и только если), вы можете использовать системную таблицу
sys.dm_db_index_usage_stats
для определения последнего обновления индекса в рассматриваемой таблице. Вы бы использовалиlast_user_update
поле.Например, чтобы получить самые последние обновленные таблицы:
Или, чтобы проверить, была ли конкретная таблица изменена с определенной даты:
источник
dm_db_index_operational_stats
отображаются проблемы (очищенные при очистке кэша метаданных), но не дляdm_db_index_usage_stats
. Единственная проблема, которую я обнаружил, была с перестроениями индекса, перезапусками сервера и отсоединением базы данных, очищающими статистику использования, и это, похоже, не применялось здесь. Было бы интересно увидеть обоснованную информацию по этому вопросу.