Как вы можете отслеживать ход обновления SQL?

Допустим, у меня есть обновление, такое как:

  UPDATE [db1].[sc1].[tb1] 
  SET c1 = LEFT(c1, LEN(c1)-1) 
  WHERE c1 like '%:'

Это обновление в основном будет проходить через миллионы строк и обрезать двоеточие, если оно есть в столбце c1.

Как я могу отслеживать, как далеко это продвинулось в таблице?

Спасибо

Это sql сервер 2008


person Matt    schedule 21.01.2011    source источник


Ответы (3)


Запросы к базе данных, особенно язык манипулирования данными (DML), являются атомарными. Это означает, что INSERT/UPDATE/DELETE либо выполняется успешно, либо нет. Невозможно увидеть, какая запись обрабатывается - в базе данных все они были изменены после того, как COMMIT был выдан после UPDATE. Даже если бы вы могли просматривать записи в процессе, к тому времени, когда вы увидели бы значение, запрос уже перешел к другим записям.

Единственный способ узнать, где находится процесс, — это написать сценарий, чтобы запрос выполнялся в цикле, поэтому вы можете использовать счетчик, чтобы узнать, сколько запросов обработано. Обычно для этого периодически фиксируются большие наборы данных, чтобы свести к минимуму риск сбоя, требующий повторного запуска всего запроса.

person OMG Ponies    schedule 21.01.2011
comment
Хотя я do согласен с разбиением его на куски для больших наборов данных, хотя для запроса, не поддерживающего индекс, может потребоваться, чтобы каждая итерация повторно посещала покрытую землю (и продвигалась дальше в таблице). - person RichardTheKiwi; 21.01.2011
comment
-1 за неправильное утверждение, что нет никакого способа, и неправильное объяснение. Within minutes, my answer gets voted down (да, это ты). - person RichardTheKiwi; 27.01.2011
comment
Любой может прочитать этот вопрос прийти к собственным выводам о том, кто сначала признается в минусовании, чтобы проверить ответ. Дело в том, что активность в вопросе делает его видимым для других, а не только для меня. Прошедшее время ничего не доказывает. Может, стоит подумать о минусовании ради реакции? - person OMG Ponies; 27.01.2011

Вы можете использовать таблицу sysindexes, которая отслеживает, насколько изменился индекс. Поскольку это делается в атомарном обновлении, у него не будет возможности пересчитать статистику, поэтому rowmodctr будет продолжать расти. Иногда это незаметно для маленьких таблиц, но для миллионов это будет видно.

-- create a test table
create table testtbl (id bigint identity primary key clustered, nv nvarchar(max))

-- fill it up with dummy data. 1/3 will have a trailing ':'
insert testtbl
select
    convert(nvarchar(max), right(a.number*b.number+c.number,30)) + 
    case when a.number %3=1 then ':' else '' end
from master..spt_values a
inner join master..spt_values b on b.type='P'
inner join master..spt_values c on c.type='P'
where a.type='P' and a.number between 1 and 5
-- (20971520 row(s) affected)

update testtbl
set nv = left(nv, len(nv)-1)
where nv like '%:'

Теперь в другом окне запроса непрерывно запускайте приведенное ниже и наблюдайте, как rowmodctr поднимается и поднимается. rowmodctr против rows дает вам представление о том, где вы находитесь, если вы знаете, где должен быть rowmodctr. В нашем случае это 67% от чуть более 2 млн.

select rows, rowmodctr
from sysindexes with (nolock)
where id = object_id('testtbl')

Не выполняйте (без блокировки) запросы на подсчет для таблицы itself, пока она обновляется.

person RichardTheKiwi    schedule 21.01.2011
comment
Интересно ваше последнее замечание. В чем вред выполнения (без блокировки) запросов на подсчет в обновляемой таблице? - person Dan; 04.09.2015
comment
@RichardTheKiwi - отличный ответ. Можно ли использовать этот метод для временных таблиц? Я хотел бы отслеживать ход обновления временной таблицы, созданной в другом окне, но, конечно, не могу ее видеть (возможно, будет достаточно временно использовать глобальную временную таблицу?) - person SQLServerSteve; 13.01.2018

Не совсем... вы можете запросить с помощью подсказки nolock и того же места, но это потребует ресурсов

Конечно, это не оптимальный запрос с ведущим подстановочным знаком...)

person gbn    schedule 21.01.2011