SQL Server - отметка времени последнего обращения к строкам - PullRequest
3 голосов
/ 17 января 2012

У меня есть таблица, которая используется в качестве общего кэша и периодически обрезается в зависимости от того, были ли недавно получены отдельные строки (т. Е. Если к строке не обращались в течение недели, она удаляется).На данный момент у меня есть столбец LastAccessed date, который я обновляю каждый раз, когда я получаю доступ к строке.

На данный момент я делаю это, выбрав запросом UPDATE и используя предложение OUTPUTна самом деле выбрать данные.Однако это довольно медленно (типичный запрос занимает несколько секунд), и меня беспокоит блокировка и одновременный доступ, поскольку многие процессы могут получить доступ к этой таблице одновременно, и им всем необходимо обновить метку времени последнего доступа.

Есть ли лучший способ сделать это?Я знаю о ROWVERSION, но это похоже на обновления, а не на выбор.Как только строка записывает в таблицу дату, она никогда не изменяется (за исключением столбца LastAccessed, на данный момент).Также, похоже, нет никаких триггеров на основе SELECT, которые я могу использовать.

Ответы [ 5 ]

3 голосов
/ 17 января 2012

Простой способ решить проблему с производительностью - изменить код для обновления записи только тогда, когда LastAccessed date старше, чем, скажем, 24 часа. Это значительно сократит количество обновлений на вашем столе.

В целом лучшим подходом может быть нормализация LastAccessed date к отдельной таблице, чтобы вам не приходилось переписывать всю строку каждый раз, когда вы ее читаете (обычно, когда вы делаете обновление, вся строка переписано где-то ). Кроме того, вы можете сделать эту таблицу обновлений кучей, в которой вы просто продолжаете вставлять новые записи в нее, а не обновляете предыдущую запись, это предотвратит любые блокировки.

Сочетание этих двух факторов поможет решить проблемы с производительностью, если к вашим данным не обращаются очень редко. Это также решит общую проблему «он блокирует всю таблицу».

Для справки ROWVERSION и TIMESTAMP не будут делать то, что вы хотите, потому что они не только обновляют только команды UPDATE, но и не отображают обратно любое значение 'datetime'. Это не рекомендуется, но вы можете выполнить произвольное отображение ROWVERSION to date, используя таблицу, в которой вы просто пишете GETDATE() и ROWVERSION (это работает, поскольку версия строки уникальна для базы данных).

0 голосов
/ 18 января 2012

Если вы используете SQL Server 2008, возможно, вы захотите проверить «Отслеживание изменений» - http://msdn.microsoft.com/en-us/library/bb933875.aspx

0 голосов
/ 17 января 2012

Это очень сложно, но возможно.

  • Создайте трассировку на стороне сервера , которая фильтрует эту таблицу (по полю object_id) и записывает результат втаблица
  • Запись триггера INSTEAD OF в таблицу результатов трассировки, которая запускает процесс TSQL или CLR, который принимает текст трассировки и метку времени в качестве параметра.
  • Анализ текста трассы и замена SELECT xxx part by UPDATE myTable SET lastAccessed = @timestamp
  • Выполнить результирующий оператор TSQL.

Это сработает, но значит ли это, что вы должны это сделать?Если вы хотите использовать систему кеширования, я думаю, вам лучше использовать настоящий кеш.SQL Server предоставляет полный ACID, который является слишком тяжелым требованием для кэша.(Когда сервер выходит из строя, вы обычно не возражаете, что ваш кэш должен быть заполнен заново)

0 голосов
/ 17 января 2012

Это невозможно с помощью встроенных инструментов Sql Server, , но , который вы можете реализовать, очень ограничен, выполняя собственный доступ к данным через хранимые процедуры

0 голосов
/ 17 января 2012
Столбец

A ROWVERSION обновляется автоматически при каждом обновлении, но он не содержит какую-либо информацию о дате или времени этого обновления (это только счетчик - нет связи с датой / временем вообще!).

В настоящее время, к сожалению, в SQL Server нет автоматического «готового» решения для этого - не существует волшебного способа отслеживать последнюю дату / время обновления. Если вам нужна эта информация - вам нужно сохранить ее самостоятельно. Единственный другой вариант: используйте ON UPDATE триггер, который бы справился с этим для вас - так что вам не нужно помнить, что он делал это для каждого оператора UPDATE ...

Обновление: ах - хорошо, так что вы хотите обновить это во время SELECT - на данный момент это абсолютно невозможно в SQL Server - просто нет доступного механизма триггера ON SELECT, поэтому я не буду Не думаю, что вы можете отследить «последний доступ» в терминах SELECT, кроме как вручную сделать это самостоятельно для каждого оператора SELECT, который у вас есть .....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...