У меня есть длительная хранимая процедура в базе данных SQL-сервера. Я не хочу, чтобы он работал чаще, чем раз в десять минут.Как установить блокировку внутри хранимой процедуры?
Как только хранимая процедура запустилась, я хочу сохранить последний результат в таблице LatestResult
против времени, и все вызовы процедуры возвращают этот результат в течение следующих десяти минут.
Это относительно просто, но мы обнаружили, что, поскольку процедура проверяет таблицу LatestResult
и обновляет ее, большие пользовательские базы получают множество взаимоблокировок, когда два пользователя одновременно называют процедуру.
В ситуации с клиентской стороны/потоком я решил бы это с помощью блокировки, имея первый пользовательский замок функции, второй пользователь встречает блокировку, ожидая результата, первый пользователь заканчивает их вызов процедуры, обновляет таблицу LatestResult
и разблокирует второго пользователя, который затем берет результат из таблицы LatestResult
.
Есть ли способ выполнить этот тип блокировки в SQL Server?
EDIT:
Это в основном, как выглядит код без его ошибки проверки вызовов:
DECLARE @LastChecked AS DATETIME
DECLARE @LastResult AS NUMERIC(18,2)
SELECT TOP 1 @LastChecked = LastRunTime, @LastResult = LastResult FROM LastResult
DECLARE @ReturnValue AS NUMERIC(18,2)
IF DATEDIFF(n, @LastChecked, GetDate()) >= 10 OR NOT @LastResult = 0
BEGIN
SELECT @ReturnValue = ABS(ISNULL(SUM(ISNULL(Amount,0)),0)) FROM Transactions WHERE ISNULL(DeletedFlag,0) = 0 GROUP BY GroupID ORDER BY ABS(ISNULL(SUM(ISNULL(Amount,0)),0))
UPDATE LastResult SET LastRunTime = GETDATE(), LastResult = @ReturnValue
SELECT @ReturnValue
END
ELSE
BEGIN
SELECT @LastResult
END
Я не совсем уверен, что происходит с группировкой, но я нашел тестовая система, в которой время выполнения составляет около 4 секунд.
Я думаю, что есть какая-то работа планируется архивировать некоторые из этих записей и сварить их до сумм для, которые, возможно, помогут вещам, учитывая, что есть несколько миллионов строк в том, что четыре второй таблице ...
Это похоже на продуманный план борьбы с медленным ходом хранимой процедуры.Сколько усилий было затрачено на оптимизацию SP? – DMason
Он в основном запускает SUM() над большинством значений в столбце, но это большой столбец, и нам нужно значение довольно часто. Лично я бы просто вызвал SUM(), но, предположительно, процедура была введена предыдущим сотрудником по другой причине, кроме как быть неудобной и вызвать взаимоблокировки. Это не большое оправдание, но это все, что у меня есть, к сожалению. – Frosty840
Можете ли вы разместить некоторый код tsql? – DMason