У нас есть база данных SQL с относительно высокой нагрузкой с учетными данными, которая размещается в облаке Azure.Чтобы рассчитать баланс пользовательских счетов, мы каждый раз суммируем все входы и выходы (таблица entry
).Я знаю, что мы могли бы сделать это по-другому, но текущее решение работает довольно хорошо в абсолютном большинстве случаев, и HTTP-запрос для получения баланса занимает в среднем ~ 134 мс (и это включает в себя гораздо больше, чем просто проблемный запрос), несмотря на то, что таблица entry
содержит сотнимиллиардов строк (у нас много учетных записей и не так много операций над каждой).
Наш SQL (слегка улучшенный после NHibernate - удалены псевдонимы столбцов и таблиц):
select AccountId, cast(sum(Amount) as DECIMAL(19,5)) as Balance
from entry
where not (Locked=1) and (AccountId in (@p0))
group by AccountId
План выполнения быстродействующего запроса (не уверен, что это полезно): Таким образом, запрос использует индекс, который включает AccountId, Locked и еще два столбца после этого.
Обычно выполняется менее чем за 100мс , но иногда ( 1 из ~ 1000 запросов ) зависает на 30 + секунд и не работаетtimeout.
Я пытался найти взаимоблокировки с помощью хранимой процедуры sp_who2
, но ничего не было найдено - на нем не было заблокированных запросов, хотя я пробовал это много раз иВ течение этого времени постоянно генерировались эпизоды.
Интересно, что у нас есть сотни запросов такого рода в минуту, но сбоев происходит один за другим, поэтому интервалы между исключениями составляют не менее 30 с иумножения на 30 (30, 60, 90, 120 секунд - 30 и 60 являются наиболее распространенными).Я не могу этого объяснить, но я полагаю, что есть некоторая работа, о которой я не знаю, которая работает как однопотоковая и блокирует определенные учетные записи.Но как я могу найти это?